Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45d2b2be77 | ||
|
|
61742efea0 |
+1
-32
@@ -47,37 +47,6 @@ Run once, by hand, on the server:
|
|||||||
# create a remote named "scaleway", type S3, matching your Scaleway
|
# create a remote named "scaleway", type S3, matching your Scaleway
|
||||||
# Object Storage credentials and region
|
# Object Storage credentials and region
|
||||||
```
|
```
|
||||||
7. Set up email notifications (optional — skip this if you don't want mail):
|
|
||||||
Install a mail transport agent (choose one):
|
|
||||||
```bash
|
|
||||||
# Option A: mailutils (Debian/Ubuntu) — includes /usr/bin/mail
|
|
||||||
apt install -y mailutils
|
|
||||||
|
|
||||||
# Option B: msmtp + mailutils (lightweight, no full MTA)
|
|
||||||
apt install -y msmtp msmtp-mta mailutils
|
|
||||||
```
|
|
||||||
Configure the recipient address. Either set `MAIL_TO` in the environment
|
|
||||||
(`/etc/environment` or the cron file itself) or edit `borg-backup.sh`:
|
|
||||||
```
|
|
||||||
MAIL_TO="${MAIL_TO:-you@example.com}"
|
|
||||||
```
|
|
||||||
If using `msmtp`, configure `/etc/msmtprc`:
|
|
||||||
```
|
|
||||||
# /etc/msmtprc — example for Gmail SMTP
|
|
||||||
defaults
|
|
||||||
auth on
|
|
||||||
tls on
|
|
||||||
tls_trust_file /etc/ssl/certs/ca-certificates.crt
|
|
||||||
|
|
||||||
account default
|
|
||||||
host smtp.gmail.com
|
|
||||||
port 587
|
|
||||||
from backup-sender@gmail.com
|
|
||||||
user backup-sender@gmail.com
|
|
||||||
password your-app-password
|
|
||||||
```
|
|
||||||
The script auto-detects which command is available (`mail` → `sendmail` → `msmtp`)
|
|
||||||
and falls back silently if none is present — notifications are never fatal.
|
|
||||||
|
|
||||||
## 2. Deploying the Scripts
|
## 2. Deploying the Scripts
|
||||||
|
|
||||||
@@ -93,9 +62,9 @@ chmod +x /opt/backup-agent/dump_db.sh
|
|||||||
## 3. Scheduling
|
## 3. Scheduling
|
||||||
|
|
||||||
Add a cron entry to run the backup daily, off-peak:
|
Add a cron entry to run the backup daily, off-peak:
|
||||||
|
|
||||||
```
|
```
|
||||||
# /etc/cron.d/borg-backup
|
# /etc/cron.d/borg-backup
|
||||||
MAIL_TO=you@example.com
|
|
||||||
30 2 * * * root /opt/backup-agent/borg-backup.sh >> /var/log/borg/cron.log 2>&1
|
30 2 * * * root /opt/backup-agent/borg-backup.sh >> /var/log/borg/cron.log 2>&1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
+2
-71
@@ -21,7 +21,7 @@ umask 077
|
|||||||
|
|
||||||
# ========================= CONFIGURATION =========================
|
# ========================= CONFIGURATION =========================
|
||||||
|
|
||||||
NAME="borg-2025"
|
NAME="chaudron"
|
||||||
REPO="/home/srv/files/backups/$NAME"
|
REPO="/home/srv/files/backups/$NAME"
|
||||||
TARGET="/home/srv/files/content"
|
TARGET="/home/srv/files/content"
|
||||||
|
|
||||||
@@ -37,8 +37,7 @@ LOGDIR="/var/log/borg"
|
|||||||
LOG_RETENTION_DAYS=90
|
LOG_RETENTION_DAYS=90
|
||||||
|
|
||||||
RCLONE_REMOTE="scaleway"
|
RCLONE_REMOTE="scaleway"
|
||||||
RCLONE_PATH="par-backup-1/$NAME"
|
RCLONE_PATH="cyanet-backups-prod/$NAME"
|
||||||
RCLONE_MAX_DELETE=200
|
|
||||||
|
|
||||||
LOCKFILE="/var/lock/borg-backup.lock"
|
LOCKFILE="/var/lock/borg-backup.lock"
|
||||||
|
|
||||||
@@ -58,10 +57,6 @@ REQUIRED_CMDS=(borg rclone docker timeout flock date find)
|
|||||||
|
|
||||||
# =================================================================
|
# =================================================================
|
||||||
|
|
||||||
# Email notification (set to your address to receive backup summary).
|
|
||||||
# Leave empty to skip notifications. The script auto-detects mail/sendmail/msmtp.
|
|
||||||
MAIL_TO="${MAIL_TO:-}"
|
|
||||||
|
|
||||||
SELF="$(readlink -f "$0")"
|
SELF="$(readlink -f "$0")"
|
||||||
mkdir -p "$LOGDIR"
|
mkdir -p "$LOGDIR"
|
||||||
LOGFILE="${BORG_BACKUP_LOGFILE:-$LOGDIR/backup-$(date +%Y-%m-%d-%H%M%S).log}"
|
LOGFILE="${BORG_BACKUP_LOGFILE:-$LOGDIR/backup-$(date +%Y-%m-%d-%H%M%S).log}"
|
||||||
@@ -93,68 +88,6 @@ run_cmd() {
|
|||||||
"$@"
|
"$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Detect available mail transport. Returns the command name or empty string.
|
|
||||||
find_mail_cmd() {
|
|
||||||
for cmd in mail sendmail msmtp; do
|
|
||||||
command -v "$cmd" >/dev/null 2>&1 && { echo "$cmd"; return 0; }
|
|
||||||
done
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Send an email notification about the backup result.
|
|
||||||
# Called from cleanup() so the log file is complete.
|
|
||||||
# Non-fatal — mail failures do not affect the backup exit code.
|
|
||||||
send_notification() {
|
|
||||||
local exit_code=$1 status started ended
|
|
||||||
[[ -n "$MAIL_TO" ]] || return 0
|
|
||||||
|
|
||||||
local mail_cmd
|
|
||||||
mail_cmd="$(find_mail_cmd)" || { log "Notification skipped: no mail command found"; return 0; }
|
|
||||||
|
|
||||||
if [ "$exit_code" -eq 0 ]; then
|
|
||||||
status="SUCCESS"
|
|
||||||
else
|
|
||||||
status="FAILED (exit $exit_code)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
started="$(head -1 "$LOGFILE" 2>/dev/null | sed -n 's/^\[\(.*\)\].*/\1/p' || echo "?")"
|
|
||||||
ended="$(date '+%F %T')"
|
|
||||||
|
|
||||||
# Build message body with headers and log tail.
|
|
||||||
{
|
|
||||||
echo "Subject: Backup $status - $(hostname -s)"
|
|
||||||
echo "To: $MAIL_TO"
|
|
||||||
echo ""
|
|
||||||
echo "===== Backup Summary ====="
|
|
||||||
echo "Host: $(hostname -f)"
|
|
||||||
echo "Archive: $ARCHIVE"
|
|
||||||
echo "Status: $status"
|
|
||||||
echo "Started: $started"
|
|
||||||
echo "Ended: $ended"
|
|
||||||
echo "Log: $LOGFILE"
|
|
||||||
echo ""
|
|
||||||
echo "----- Last 80 lines of backup log -----"
|
|
||||||
tail -80 "$LOGFILE" 2>/dev/null || echo "(log unavailable)"
|
|
||||||
} | case "$mail_cmd" in
|
|
||||||
mail)
|
|
||||||
mail -s "Backup $status - $(hostname -s)" "$MAIL_TO"
|
|
||||||
;;
|
|
||||||
sendmail)
|
|
||||||
sendmail "$MAIL_TO"
|
|
||||||
;;
|
|
||||||
msmtp)
|
|
||||||
msmtp "$MAIL_TO"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
local rc=$?
|
|
||||||
if [ "$rc" -eq 0 ]; then
|
|
||||||
log "Notification sent to $MAIL_TO (via $mail_cmd)"
|
|
||||||
else
|
|
||||||
log "WARNING: notification via $mail_cmd failed (exit $rc)"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
container_running() {
|
container_running() {
|
||||||
[[ "$(docker inspect -f '{{.State.Running}}' "$1" 2>/dev/null || echo false)" == "true" ]]
|
[[ "$(docker inspect -f '{{.State.Running}}' "$1" 2>/dev/null || echo false)" == "true" ]]
|
||||||
}
|
}
|
||||||
@@ -209,7 +142,6 @@ cleanup() {
|
|||||||
log "=== Backup FAILED (exit $exit_code) ==="
|
log "=== Backup FAILED (exit $exit_code) ==="
|
||||||
fi
|
fi
|
||||||
log "Full log: $LOGFILE"
|
log "Full log: $LOGFILE"
|
||||||
send_notification "$exit_code"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Returns 0 if the repo is encrypted, 1 if not.
|
# Returns 0 if the repo is encrypted, 1 if not.
|
||||||
@@ -371,5 +303,4 @@ run_cmd timeout "$SYNC_TIMEOUT" \
|
|||||||
--retries-sleep 10s \
|
--retries-sleep 10s \
|
||||||
--low-level-retries 20 \
|
--low-level-retries 20 \
|
||||||
--s3-no-check-bucket \
|
--s3-no-check-bucket \
|
||||||
--max-delete "$RCLONE_MAX_DELETE" \
|
|
||||||
"$REPO" "${RCLONE_REMOTE}:${RCLONE_PATH}"
|
"$REPO" "${RCLONE_REMOTE}:${RCLONE_PATH}"
|
||||||
|
|||||||
Reference in New Issue
Block a user