Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d98d945b1 |
+32
-1
@@ -47,6 +47,37 @@ 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
|
||||||
|
|
||||||
@@ -62,9 +93,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
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,10 @@ 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}"
|
||||||
@@ -89,6 +93,68 @@ 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" ]]
|
||||||
}
|
}
|
||||||
@@ -143,6 +209,7 @@ 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.
|
||||||
|
|||||||
Reference in New Issue
Block a user