← Kembali

Bash Menengah Backup

Backup folder dengan timestamp + retention 7 hari

Snapshot folder ke tar.gz dengan nama timestamp, lalu hapus backup lebih dari 7 hari. Cocok untuk cron daily.

Dipublikasikan 24 Mei 2026

Backup harian directory penting (database dump, config, upload) ke tar.gz dengan timestamp di nama file, plus auto-prune backup yang umurnya > 7 hari. Cron 0 2 * * * setiap dinihari pukul 02:00.

Kode

#!/usr/bin/env bash
# backup.sh — Snapshot directory ke backup dir, retention 7 hari.
# Usage: ./backup.sh /path/to/source /path/to/backup/dir

set -euo pipefail

SOURCE_DIR="${1:?Usage: backup.sh <source> <backup-dir> [retention-days]}"
BACKUP_DIR="${2:?Usage: backup.sh <source> <backup-dir> [retention-days]}"
RETENTION_DAYS="${3:-7}"

if [ ! -d "$SOURCE_DIR" ]; then
  echo "Error: source '$SOURCE_DIR' tidak ada" >&2
  exit 1
fi

mkdir -p "$BACKUP_DIR"

# Nama backup: <basename-source>-YYYY-MM-DD-HHMMSS.tar.gz
SOURCE_NAME=$(basename "$SOURCE_DIR")
TIMESTAMP=$(date +"%Y-%m-%d-%H%M%S")
BACKUP_FILE="${BACKUP_DIR}/${SOURCE_NAME}-${TIMESTAMP}.tar.gz"

echo "Backup mulai: $SOURCE_DIR$BACKUP_FILE"
START=$(date +%s)

# Tar dengan progress (jika pv tersedia)
if command -v pv >/dev/null 2>&1; then
  tar -cf - -C "$(dirname "$SOURCE_DIR")" "$(basename "$SOURCE_DIR")" \
    | pv -s "$(du -sb "$SOURCE_DIR" | awk '{print $1}')" \
    | gzip > "$BACKUP_FILE"
else
  tar -czf "$BACKUP_FILE" -C "$(dirname "$SOURCE_DIR")" "$(basename "$SOURCE_DIR")"
fi

END=$(date +%s)
DURATION=$((END - START))
SIZE=$(du -h "$BACKUP_FILE" | awk '{print $1}')

echo "Selesai: ${SIZE} dalam ${DURATION} detik"

# Retention: hapus backup lebih lama dari N hari
echo "Cleanup backup > ${RETENTION_DAYS} hari..."
find "$BACKUP_DIR" -name "${SOURCE_NAME}-*.tar.gz" -type f \
  -mtime "+${RETENTION_DAYS}" -print -delete

echo "Backup selesai."

Cara pakai

# Manual run
./backup.sh /var/www/uploads /backup/uploads

# Dengan custom retention (14 hari)
./backup.sh /var/www/uploads /backup/uploads 14

# Cron daily 02:00
# crontab -e
0 2 * * * /home/user/backup.sh /var/www/uploads /backup/uploads >> /var/log/backup.log 2>&1

Kapan dipakai

  • VPS kecil dengan satu aplikasi web — sebelum invest ke backup service penuh seperti Backblaze atau Restic.
  • Backup database dump (MySQL, Postgres) yang sudah di-export ke folder.
  • Snapshot folder uploads/ user-generated content.

Catatan

  • find -mtime +N beda makna di Linux vs macOS — di macOS pakai mtime modification, di Linux secara default sama. Snippet ini bekerja di keduanya.
  • tar retain permission, ownership, dan symlink — file dump database biasanya cocok. Tapi tar tidak handle sparse file well — kalau backup VM image, pakai tool lain.
  • Retention berdasarkan mtime file backup, bukan tanggal di nama. Aman selama tidak ada yang touch file backup.
  • Untuk backup ke remote storage (S3, R2, B2), tambahkan baris setelah create:
# Upload ke Cloudflare R2 via rclone
rclone copy "$BACKUP_FILE" "r2:backup-bucket/$(basename "$BACKUP_FILE")"

Cron harus tahu PATH. Set PATH=/usr/local/bin:/usr/bin:/bin di top crontab — banyak orang lupa, lalu command not found: tar di log.

# tags

backuptarcronretention

← Semua snippet Snippet Bash lain →