#!/usr/bin/env bash # Daily backup of the mail stack. Designed for cron. # # Crontab (deeily): # 30 3 * * * /home/deeily/mail/deploy/backup.sh >>/var/log/mail-backup.log 2>&1 # # Vars (override via /home/deeily/mail/.env or systemd env): # BACKUP_DIR — куда писать архивы (default /var/backups/mail) # BACKUP_RETAIN — сколько ежедневных оставлять (default 14) # POSTGRES_USER, POSTGRES_DB — для pg_dump (default mail/mail) # DMS_DATA_DIR — куда DMS пишет /var/mail (default /home/deeily/mail/docker/dms-data) set -euo pipefail # shellcheck disable=SC1091 [ -f /home/deeily/mail/.env ] && set -a && . /home/deeily/mail/.env && set +a BACKUP_DIR="${BACKUP_DIR:-/var/backups/mail}" RETAIN="${BACKUP_RETAIN:-14}" PG_USER="${POSTGRES_USER:-mail}" PG_DB="${POSTGRES_DB:-mail}" DMS_DATA_DIR="${DMS_DATA_DIR:-/home/deeily/mail/docker/dms-data}" PG_CONTAINER="${PG_CONTAINER:-docker-postgres-1}" REDIS_CONTAINER="${REDIS_CONTAINER:-docker-redis-1}" mkdir -p "$BACKUP_DIR" TS=$(date +%Y%m%d-%H%M) TARGET="$BACKUP_DIR/$TS" mkdir -p "$TARGET" echo "[$(date -Is)] backup → $TARGET" # 1. Postgres dump echo " postgres…" docker exec "$PG_CONTAINER" pg_dump -U "$PG_USER" -F c "$PG_DB" \ | gzip -9 > "$TARGET/postgres-$PG_DB.dump.gz" # 2. Redis snapshot echo " redis…" docker exec "$REDIS_CONTAINER" sh -c 'redis-cli SAVE >/dev/null && cat /data/dump.rdb' \ | gzip -9 > "$TARGET/redis.rdb.gz" # 3. DMS maildir + config (rsync hardlinked snapshot) if [ -d "$DMS_DATA_DIR" ]; then echo " maildir…" tar -C "$(dirname "$DMS_DATA_DIR")" --warning=no-file-changed -czf "$TARGET/dms-data.tar.gz" "$(basename "$DMS_DATA_DIR")" || true fi if [ -d /home/deeily/mail/docker/dms-config ]; then echo " dms-config…" tar -C /home/deeily/mail/docker -czf "$TARGET/dms-config.tar.gz" dms-config fi # 4. .env (только структура — пароли в шифрованных файлах не нужны) cp /home/deeily/mail/.env "$TARGET/env.snapshot" 2>/dev/null || true chmod 600 "$TARGET/env.snapshot" 2>/dev/null || true # 5. Wrap up SIZE=$(du -sh "$TARGET" | awk '{print $1}') echo " done, total $SIZE" # 6. Retain only last N daily snapshots ls -1d "$BACKUP_DIR"/[0-9]* 2>/dev/null | sort -r | tail -n +$((RETAIN+1)) | xargs -r rm -rf echo "[$(date -Is)] backup ok"