#!/usr/bin/env bash # Kakeibo veritabanı yedeği: MongoDB konteynerinde mongodump → sıkıştırılmış tek dosya. # # Canlı (Atlas, root): /usr/local/lib/kakeibo/backup.sh # Yerel: npm run db:backup (kakeibo_dev → ./backups) # # Ayarlar (ortam değişkeni): # MONGO_SERVICE Dokploy/Swarm servis adı (konteyner bundan bulunur) [kakeibo-kakeibomongo-fibzhc] # MONGO_CONTAINER Konteyner adı doğrudan (verilirse MONGO_SERVICE kullanılmaz) # DB_NAME Yedeklenecek veritabanı [kakeibo] # BACKUP_DIR Yedek klasörü [/var/backups/kakeibo] # KEEP Saklanacak yedek sayısı (en yeniler) [14] # BACKUP_GROUP Verilirse klasör/dosyalar bu gruba okunur yapılır (yedeği çeken SSH kullanıcısı için) # # Her yedek: yazılır → gzip bütünlüğü + mongorestore --dryRun ile denetlenir → ancak sonra adı verilir. # Hata olursa çıkış kodu ≠ 0 (systemd günlüğünde görünür), yarım dosya kalmaz. set -euo pipefail MONGO_SERVICE=${MONGO_SERVICE:-kakeibo-kakeibomongo-fibzhc} DB_NAME=${DB_NAME:-kakeibo} BACKUP_DIR=${BACKUP_DIR:-/var/backups/kakeibo} KEEP=${KEEP:-14} log() { echo "[kakeibo-backup] $*"; } die() { echo "[kakeibo-backup] HATA: $*" >&2; exit 1; } container=${MONGO_CONTAINER:-} if [[ -z $container ]]; then container=$(docker ps -q -f "label=com.docker.swarm.service.name=$MONGO_SERVICE" | head -n1) [[ -n $container ]] || container=$(docker ps -q -f "name=$MONGO_SERVICE" | head -n1) fi [[ -n $container ]] || die "MongoDB konteyneri bulunamadı ($MONGO_SERVICE). Servis çalışıyor mu?" umask 027 mkdir -p "$BACKUP_DIR" if [[ -n ${BACKUP_GROUP:-} ]]; then chgrp "$BACKUP_GROUP" "$BACKUP_DIR" chmod 750 "$BACKUP_DIR" fi stamp=$(date +%Y-%m-%d_%H%M) file="$BACKUP_DIR/$DB_NAME-$stamp.archive.gz" tmp="$file.partial" trap 'rm -f "$tmp"' EXIT log "$DB_NAME yedekleniyor → $file" docker exec "$container" mongodump --db="$DB_NAME" --archive --gzip --quiet > "$tmp" \ || die "mongodump başarısız" [[ -s $tmp ]] || die "yedek dosyası boş" gzip -t "$tmp" || die "yedek dosyası bozuk (gzip)" docker exec -i "$container" mongorestore --archive --gzip --dryRun --quiet \ --nsInclude="$DB_NAME.*" < "$tmp" || die "yedek okunamadı (mongorestore --dryRun)" mv "$tmp" "$file" [[ -n ${BACKUP_GROUP:-} ]] && chgrp "$BACKUP_GROUP" "$file" log "tamam: $(du -h "$file" | cut -f1)" # Eski yedekler: en yeni $KEEP tanesi kalır (gün atlansa da sayı korunur) mapfile -t old < <(ls -1t "$BACKUP_DIR"/"$DB_NAME"-*.archive.gz | tail -n +"$((KEEP + 1))") for f in "${old[@]}"; do rm -f -- "$f" log "silindi (eski): $(basename "$f")" done