На главную

Shell и скрипты

Скрипт резервного копирования

Скрипт резервного копирования: каталоги и дамп базы в архив с контрольными суммами, отправка на другой сервер или в S3, чистка старых копий, защита от одновременного запуска и уведомление в ntfy.

Что копируем

По одному на строку

Шаблоны для tar: *.log, cache/*

Куда и надолго ли

Копии от 1-го числа живут дольше

Например https://ntfy.sh/ваш-топик. Пусто — без уведомлений

Запуск по расписанию

30 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Проверьте восстановление: копия, из которой ни разу не восстанавливали, копией не считается.

backup.sh

#!/usr/bin/env bash
# Резервная копия. Поставьте в cron и проверьте восстановление хотя бы раз.

set -euo pipefail

BACKUP_ROOT="/backup"
STAMP="$(date +%F_%H%M)"
WORK="$BACKUP_ROOT/$STAMP"
LOG="$BACKUP_ROOT/backup.log"

log() { printf '%s %s\n' "$(date +%F\ %T)" "$*" | tee -a "$LOG" >&2; }
fail() { log "ОШИБКА: $*"; exit 1; }

LOCK="/var/lock/$(basename "$0").lock"
exec 9>"$LOCK" || fail "не открыть файл блокировки"
flock -n 9 || { log "копия уже идёт, выходим"; exit 0; }

mkdir -p "$WORK" || fail "не создать $WORK"
log "старт"

sudo -u "postgres" pg_dump --format=custom "app" > "$WORK/db.dump" || fail "pg_dump"
log "дамп базы готов: $(du -h "$WORK/db.dump" | cut -f1)"

nice -n 19 ionice -c3 tar -czf "$WORK/files.tar.gz" --exclude="*.log" --exclude="cache/*" "/var/www" "/etc/nginx" || fail "tar"
log "архив файлов готов: $(du -h "$WORK/files.tar.gz" | cut -f1)"

sha256sum "$WORK"/* > "$WORK/SHA256SUMS"

# Чистка: дневные копии храним ограниченное время, первое число месяца — дольше
find "$BACKUP_ROOT" -mindepth 1 -maxdepth 1 -type d -name '20*' -mtime +7 ! -name '*-01_*' -exec rm -rf {} + || true
find "$BACKUP_ROOT" -mindepth 1 -maxdepth 1 -type d -name '*-01_*' -mtime +186 -exec rm -rf {} + || true

SIZE="$(du -sh "$WORK" | cut -f1)"
log "готово, размер $SIZE"