Merge pull request 'Fix' (#1) from pscriptos/docker-backup-sftp-uploader:fix into main
Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
.gitattributes text eol=lf
|
||||||
|
*.sh text eol=lf
|
||||||
|
*.md text eol=lf
|
||||||
|
*.conf text eol=lf
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
# Docker Backup SFTP Uploader
|
||||||
|
|
||||||
|
Dieses Repository enthält ein Bash-Script, das ein Docker-Compose-Projekt kurz stoppt, das Projektverzeichnis als `tar.gz` archiviert, das Archiv per SFTP hochlädt und optional eine Status-Mail verschickt.
|
||||||
|
|
||||||
|
## Nutzung
|
||||||
|
|
||||||
|
Voraussetzungen auf dem Server:
|
||||||
|
|
||||||
|
- `docker` mit Compose-Plugin
|
||||||
|
- `tar` und `gzip`
|
||||||
|
- `sshpass` und `sftp`
|
||||||
|
- optional `mail` für Status-Mails
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod +x docker-backup-sftp-uploader.sh
|
||||||
|
./docker-backup-sftp-uploader.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Die Konfiguration liegt in `docker-backup-sftp-uploader.conf` neben dem Script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
SFTP_HOST="backup.example.com"
|
||||||
|
SFTP_PORT="22"
|
||||||
|
SFTP_USER="backup-user"
|
||||||
|
SFTP_PASS="secret"
|
||||||
|
SFTP_REMOTE_DIR="/uploads"
|
||||||
|
MAIL_TO="admin@example.com"
|
||||||
|
MAIL_FROM="backup@example.com"
|
||||||
|
BACKUP_DIR="/srv/backups/docker-backup-sftp-uploader"
|
||||||
|
LOG_DIR="/srv/backups/docker-backup-sftp-uploader/logs"
|
||||||
|
KEEP_LOCAL_BACKUP="false"
|
||||||
|
MIN_FREE_MB="1024"
|
||||||
|
```
|
||||||
|
|
||||||
|
Danach reicht:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./docker-backup-sftp-uploader.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Falls eine andere Konfigurationsdatei genutzt werden soll:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
CONFIG_FILE="/etc/docker-backup-sftp-uploader.conf" ./docker-backup-sftp-uploader.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Wichtige Hinweise
|
||||||
|
|
||||||
|
- Archive und Logs werden nicht mehr in `/tmp` geschrieben. Standard ist ein Backup-Ordner neben dem Projektverzeichnis.
|
||||||
|
- Vor dem Stoppen von Docker prüft das Script, ob am Backup-Ziel genug Speicher frei ist.
|
||||||
|
- Bei Fehlern versucht das Script, Docker wieder zu starten.
|
||||||
|
- Der Upload erfolgt zuerst als `.part`-Datei und wird nach erfolgreichem Transfer auf den finalen Namen umbenannt.
|
||||||
|
- Mailversand ist nur aktiv, wenn `MAIL_TO` gesetzt ist und das System ein funktionierendes `mail`-Kommando besitzt.
|
||||||
|
|
||||||
|
Weitere Details stehen in [docs/README.md](docs/README.md).
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
########################################
|
||||||
|
# Docker Backup SFTP Uploader
|
||||||
|
# Konfiguration
|
||||||
|
########################################
|
||||||
|
|
||||||
|
SFTP_HOST="sftp.example.com"
|
||||||
|
SFTP_PORT="22"
|
||||||
|
SFTP_USER="user"
|
||||||
|
SFTP_PASS="Tpassw0rd"
|
||||||
|
SFTP_REMOTE_DIR="/uploads"
|
||||||
|
|
||||||
|
MAIL_TO=""
|
||||||
|
MAIL_FROM=""
|
||||||
|
|
||||||
|
# Nicht /tmp verwenden: viele Systeme mounten /tmp klein oder als tmpfs.
|
||||||
|
# Der Standard legt den Backup-Ordner neben dem Projektverzeichnis ab.
|
||||||
|
BACKUP_DIR=""
|
||||||
|
LOG_DIR=""
|
||||||
|
|
||||||
|
# true = lokales Archiv nach erfolgreichem Upload behalten
|
||||||
|
KEEP_LOCAL_BACKUP="false"
|
||||||
|
|
||||||
|
# Zusätzlicher freier Speicher in MB, der neben der Quellgröße vorhanden sein muss.
|
||||||
|
MIN_FREE_MB="1024"
|
||||||
+245
-55
@@ -1,31 +1,51 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -o pipefail
|
set -Eeuo pipefail
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Konfiguration
|
# Script- und Konfigurationspfade
|
||||||
########################################
|
########################################
|
||||||
|
|
||||||
SFTP_HOST="sftp.example.com"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
SFTP_PORT="22"
|
DIR_NAME="$(basename "$SCRIPT_DIR")"
|
||||||
SFTP_USER="user"
|
CONFIG_FILE="${CONFIG_FILE:-${SCRIPT_DIR}/docker-backup-sftp-uploader.conf}"
|
||||||
SFTP_PASS="Tpassw0rd"
|
|
||||||
SFTP_REMOTE_DIR="/uploads"
|
|
||||||
|
|
||||||
MAIL_TO=""
|
if [[ -f "$CONFIG_FILE" ]]; then
|
||||||
MAIL_FROM=""
|
# shellcheck source=/dev/null
|
||||||
|
source "$CONFIG_FILE"
|
||||||
|
else
|
||||||
|
echo "FEHLER: Konfigurationsdatei nicht gefunden: $CONFIG_FILE" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# Optionale Fallbacks
|
||||||
|
########################################
|
||||||
|
|
||||||
|
: "${SFTP_PORT:=22}"
|
||||||
|
: "${MAIL_TO:=}"
|
||||||
|
: "${MAIL_FROM:=}"
|
||||||
|
: "${BACKUP_DIR:=$(dirname "$SCRIPT_DIR")/${DIR_NAME}_backups}"
|
||||||
|
: "${LOG_DIR:=${BACKUP_DIR}/logs}"
|
||||||
|
: "${KEEP_LOCAL_BACKUP:=false}"
|
||||||
|
: "${MIN_FREE_MB:=1024}"
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Variablen
|
# Variablen
|
||||||
########################################
|
########################################
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
DATE="$(date +"%Y-%m-%d_%H-%M-%S")"
|
||||||
DIR_NAME="$(basename "$SCRIPT_DIR")"
|
|
||||||
|
|
||||||
DATE=$(date +"%Y-%m-%d_%H-%M-%S")
|
|
||||||
BACKUP_FILE="${DIR_NAME}_${DATE}.tar.gz"
|
BACKUP_FILE="${DIR_NAME}_${DATE}.tar.gz"
|
||||||
|
|
||||||
LOGFILE="/tmp/${DIR_NAME}_backup.log"
|
mkdir -p "$BACKUP_DIR" "$LOG_DIR"
|
||||||
|
BACKUP_DIR="$(cd "$BACKUP_DIR" && pwd)"
|
||||||
|
LOG_DIR="$(cd "$LOG_DIR" && pwd)"
|
||||||
|
|
||||||
|
BACKUP_PATH="${BACKUP_DIR}/${BACKUP_FILE}"
|
||||||
|
LOGFILE="${LOG_DIR}/${DIR_NAME}_backup_${DATE}.log"
|
||||||
|
|
||||||
|
DOCKER_STOPPED=false
|
||||||
|
SUCCESS=false
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Logging
|
# Logging
|
||||||
@@ -34,28 +54,102 @@ LOGFILE="/tmp/${DIR_NAME}_backup.log"
|
|||||||
exec > >(tee -a "$LOGFILE")
|
exec > >(tee -a "$LOGFILE")
|
||||||
exec 2>&1
|
exec 2>&1
|
||||||
|
|
||||||
echo "========================================="
|
log() {
|
||||||
echo "Backup gestartet: $(date)"
|
echo "[$(date +"%Y-%m-%d %H:%M:%S")] $*"
|
||||||
echo "Projekt: $DIR_NAME"
|
}
|
||||||
echo "========================================="
|
|
||||||
|
log "========================================="
|
||||||
|
log "Backup gestartet"
|
||||||
|
log "Projekt: $DIR_NAME"
|
||||||
|
log "Konfiguration: $CONFIG_FILE"
|
||||||
|
log "Backup-Datei: $BACKUP_PATH"
|
||||||
|
log "Log-Datei: $LOGFILE"
|
||||||
|
log "========================================="
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Fehlerbehandlung
|
# Hilfsfunktionen
|
||||||
########################################
|
########################################
|
||||||
|
|
||||||
|
require_command() {
|
||||||
|
local command_name="$1"
|
||||||
|
|
||||||
|
if ! command -v "$command_name" >/dev/null 2>&1; then
|
||||||
|
log "FEHLER: Benötigtes Kommando fehlt: $command_name"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
require_config_value() {
|
||||||
|
local variable_name="$1"
|
||||||
|
|
||||||
|
if [[ -z "${!variable_name:-}" ]]; then
|
||||||
|
log "FEHLER: Pflichtwert fehlt in der Konfiguration: $variable_name"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
send_mail() {
|
||||||
|
local subject="$1"
|
||||||
|
local body="$2"
|
||||||
|
|
||||||
|
if [[ -z "$MAIL_TO" ]]; then
|
||||||
|
log "Hinweis: MAIL_TO ist leer, Mailversand wird übersprungen."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v mail >/dev/null 2>&1; then
|
||||||
|
log "WARNUNG: Kommando 'mail' wurde nicht gefunden, Mailversand nicht möglich."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$MAIL_FROM" ]]; then
|
||||||
|
if printf '%s\n' "$body" | mail -r "$MAIL_FROM" -s "$subject" "$MAIL_TO"; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "WARNUNG: Mailversand mit MAIL_FROM fehlgeschlagen, versuche ohne Absenderoption."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! printf '%s\n' "$body" | mail -s "$subject" "$MAIL_TO"; then
|
||||||
|
log "WARNUNG: Mailversand fehlgeschlagen."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
send_error_mail() {
|
send_error_mail() {
|
||||||
|
local exit_code="$1"
|
||||||
|
local body
|
||||||
|
|
||||||
SUBJECT="❌ Backup FEHLGESCHLAGEN - ${DIR_NAME}"
|
body="$(cat <<EOF
|
||||||
|
Backup fehlgeschlagen.
|
||||||
|
|
||||||
mail -s "$SUBJECT" "$MAIL_TO" < "$LOGFILE"
|
Projekt:
|
||||||
|
${DIR_NAME}
|
||||||
|
|
||||||
|
Datum:
|
||||||
|
$(date)
|
||||||
|
|
||||||
|
Exit-Code:
|
||||||
|
${exit_code}
|
||||||
|
|
||||||
|
Log-Datei:
|
||||||
|
${LOGFILE}
|
||||||
|
|
||||||
|
Log:
|
||||||
|
|
||||||
|
$(cat "$LOGFILE" 2>/dev/null || true)
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
|
||||||
|
send_mail "Backup FEHLGESCHLAGEN - ${DIR_NAME}" "$body"
|
||||||
}
|
}
|
||||||
|
|
||||||
send_success_mail() {
|
send_success_mail() {
|
||||||
|
local size
|
||||||
|
local body
|
||||||
|
|
||||||
SIZE=$(du -h "/tmp/${BACKUP_FILE}" | awk '{print $1}')
|
size="$(du -h "$BACKUP_PATH" | awk '{print $1}')"
|
||||||
|
|
||||||
mail -s "✅ Backup erfolgreich - ${DIR_NAME} (${SIZE})" "$MAIL_TO" << EOF
|
|
||||||
|
|
||||||
|
body="$(cat <<EOF
|
||||||
Backup erfolgreich abgeschlossen.
|
Backup erfolgreich abgeschlossen.
|
||||||
|
|
||||||
Projekt:
|
Projekt:
|
||||||
@@ -67,38 +161,141 @@ $(date)
|
|||||||
Backup:
|
Backup:
|
||||||
${BACKUP_FILE}
|
${BACKUP_FILE}
|
||||||
|
|
||||||
Größe:
|
Groesse:
|
||||||
${SIZE}
|
${size}
|
||||||
|
|
||||||
|
Remote-Ziel:
|
||||||
|
${SFTP_HOST}:${SFTP_REMOTE_DIR}/${BACKUP_FILE}
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
|
|
||||||
$(cat "$LOGFILE")
|
$(cat "$LOGFILE")
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
|
)"
|
||||||
|
|
||||||
|
send_mail "Backup erfolgreich - ${DIR_NAME} (${size})" "$body"
|
||||||
}
|
}
|
||||||
|
|
||||||
trap 'send_error_mail; exit 1' ERR
|
cleanup_local_backup() {
|
||||||
|
if [[ "$KEEP_LOCAL_BACKUP" == "true" ]]; then
|
||||||
|
log "Lokales Backup bleibt erhalten: $BACKUP_PATH"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "$BACKUP_PATH" ]]; then
|
||||||
|
log "Entferne lokales Backup: $BACKUP_PATH"
|
||||||
|
rm -f "$BACKUP_PATH"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
start_docker_if_needed() {
|
||||||
|
if [[ "$DOCKER_STOPPED" == "true" ]]; then
|
||||||
|
log "Starte Docker..."
|
||||||
|
docker compose up -d
|
||||||
|
DOCKER_STOPPED=false
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
on_error() {
|
||||||
|
local exit_code="$?"
|
||||||
|
|
||||||
|
log "FEHLER: Backup fehlgeschlagen (Exit-Code: ${exit_code})."
|
||||||
|
|
||||||
|
if [[ "$DOCKER_STOPPED" == "true" ]]; then
|
||||||
|
log "Versuche Docker nach Fehler wieder zu starten..."
|
||||||
|
if docker compose up -d; then
|
||||||
|
DOCKER_STOPPED=false
|
||||||
|
log "Docker wurde nach Fehler wieder gestartet."
|
||||||
|
else
|
||||||
|
log "WARNUNG: Docker konnte nach Fehler nicht gestartet werden."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
send_error_mail "$exit_code"
|
||||||
|
cleanup_local_backup
|
||||||
|
exit "$exit_code"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_exit() {
|
||||||
|
local exit_code="$?"
|
||||||
|
|
||||||
|
if [[ "$SUCCESS" == "true" ]]; then
|
||||||
|
cleanup_local_backup
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit "$exit_code"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_free_space() {
|
||||||
|
local source_kb
|
||||||
|
local required_kb
|
||||||
|
local free_kb
|
||||||
|
local min_free_kb
|
||||||
|
|
||||||
|
source_kb="$(du -sk "$SCRIPT_DIR" | awk '{print $1}')"
|
||||||
|
min_free_kb=$((MIN_FREE_MB * 1024))
|
||||||
|
required_kb=$((source_kb + (source_kb / 10) + min_free_kb))
|
||||||
|
free_kb="$(df -Pk "$BACKUP_DIR" | awk 'NR == 2 {print $4}')"
|
||||||
|
|
||||||
|
log "Quellgroesse: $((source_kb / 1024)) MB"
|
||||||
|
log "Freier Speicher am Backup-Ziel: $((free_kb / 1024)) MB"
|
||||||
|
log "Geschaetzter Mindestbedarf: $((required_kb / 1024)) MB"
|
||||||
|
|
||||||
|
if (( free_kb < required_kb )); then
|
||||||
|
log "FEHLER: Zu wenig freier Speicher in $BACKUP_DIR."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_backup_dir_location() {
|
||||||
|
case "$BACKUP_DIR" in
|
||||||
|
"$SCRIPT_DIR"|"$SCRIPT_DIR"/*)
|
||||||
|
log "FEHLER: BACKUP_DIR darf nicht innerhalb des Projektverzeichnisses liegen."
|
||||||
|
log "Projektverzeichnis: $SCRIPT_DIR"
|
||||||
|
log "Backup-Verzeichnis: $BACKUP_DIR"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
trap on_error ERR
|
||||||
|
trap on_exit EXIT
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# Vorbedingungen
|
||||||
|
########################################
|
||||||
|
|
||||||
|
cd "$SCRIPT_DIR"
|
||||||
|
|
||||||
|
require_command docker
|
||||||
|
require_command tar
|
||||||
|
require_command gzip
|
||||||
|
require_command sshpass
|
||||||
|
require_command sftp
|
||||||
|
require_config_value SFTP_HOST
|
||||||
|
require_config_value SFTP_USER
|
||||||
|
require_config_value SFTP_PASS
|
||||||
|
require_config_value SFTP_REMOTE_DIR
|
||||||
|
check_backup_dir_location
|
||||||
|
check_free_space
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Docker stoppen
|
# Docker stoppen
|
||||||
########################################
|
########################################
|
||||||
|
|
||||||
cd "$SCRIPT_DIR"
|
log "Stoppe Docker..."
|
||||||
|
|
||||||
echo "Stoppe Docker..."
|
|
||||||
|
|
||||||
docker compose down
|
docker compose down
|
||||||
|
DOCKER_STOPPED=true
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Archiv erstellen
|
# Archiv erstellen
|
||||||
########################################
|
########################################
|
||||||
|
|
||||||
echo "Erstelle Backup..."
|
log "Erstelle Backup..."
|
||||||
|
|
||||||
tar \
|
tar \
|
||||||
--same-owner \
|
--same-owner \
|
||||||
--preserve-permissions \
|
--preserve-permissions \
|
||||||
-czpf "/tmp/${BACKUP_FILE}" \
|
-czpf "$BACKUP_PATH" \
|
||||||
-C "$(dirname "$SCRIPT_DIR")" \
|
-C "$(dirname "$SCRIPT_DIR")" \
|
||||||
"$DIR_NAME"
|
"$DIR_NAME"
|
||||||
|
|
||||||
@@ -106,27 +303,28 @@ tar \
|
|||||||
# Docker starten
|
# Docker starten
|
||||||
########################################
|
########################################
|
||||||
|
|
||||||
echo "Starte Docker..."
|
start_docker_if_needed
|
||||||
|
|
||||||
docker compose up -d
|
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Upload
|
# Upload
|
||||||
########################################
|
########################################
|
||||||
|
|
||||||
echo "Upload nach ${SFTP_HOST}..."
|
log "Upload nach ${SFTP_HOST}:${SFTP_REMOTE_DIR}..."
|
||||||
|
|
||||||
sshpass -p "$SFTP_PASS" sftp \
|
sshpass -p "$SFTP_PASS" sftp \
|
||||||
-oPort="$SFTP_PORT" \
|
-P "$SFTP_PORT" \
|
||||||
|
-oBatchMode=no \
|
||||||
-oStrictHostKeyChecking=no \
|
-oStrictHostKeyChecking=no \
|
||||||
|
-oServerAliveInterval=30 \
|
||||||
|
-oServerAliveCountMax=10 \
|
||||||
"${SFTP_USER}@${SFTP_HOST}" << EOF
|
"${SFTP_USER}@${SFTP_HOST}" << EOF
|
||||||
|
cd "${SFTP_REMOTE_DIR}"
|
||||||
cd ${SFTP_REMOTE_DIR}
|
put "${BACKUP_PATH}" "${BACKUP_FILE}.part"
|
||||||
put /tmp/${BACKUP_FILE}
|
rename "${BACKUP_FILE}.part" "${BACKUP_FILE}"
|
||||||
bye
|
bye
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
echo "Upload erfolgreich."
|
log "Upload erfolgreich."
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# Erfolgsmail
|
# Erfolgsmail
|
||||||
@@ -134,13 +332,5 @@ echo "Upload erfolgreich."
|
|||||||
|
|
||||||
send_success_mail
|
send_success_mail
|
||||||
|
|
||||||
########################################
|
SUCCESS=true
|
||||||
# Aufräumen
|
log "Backup beendet: $(date)"
|
||||||
########################################
|
|
||||||
|
|
||||||
rm -f "/tmp/${BACKUP_FILE}"
|
|
||||||
|
|
||||||
echo "Backup beendet: $(date)"
|
|
||||||
exec 1>&-
|
|
||||||
exec 2>&-
|
|
||||||
exit 0
|
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
# Dokumentation
|
||||||
|
|
||||||
|
## Ablauf
|
||||||
|
|
||||||
|
1. Das Script ermittelt das Projektverzeichnis.
|
||||||
|
2. Es lädt `docker-backup-sftp-uploader.conf` aus demselben Verzeichnis.
|
||||||
|
3. Es legt Backup- und Log-Verzeichnis an.
|
||||||
|
4. Es prüft benötigte Kommandos, Pflichtwerte und freien Speicher.
|
||||||
|
5. Es stoppt Docker mit `docker compose down`.
|
||||||
|
6. Es erstellt ein `tar.gz`-Archiv des Projektordners.
|
||||||
|
7. Es startet Docker mit `docker compose up -d`.
|
||||||
|
8. Es lädt das Archiv per SFTP hoch.
|
||||||
|
9. Es verschickt bei Erfolg oder Fehler eine Mail, sofern Mailversand konfiguriert ist.
|
||||||
|
10. Es löscht das lokale Archiv, außer `KEEP_LOCAL_BACKUP=true` ist gesetzt.
|
||||||
|
|
||||||
|
## Konfiguration
|
||||||
|
|
||||||
|
Die Konfiguration liegt standardmäßig in `docker-backup-sftp-uploader.conf` neben dem Script. Alternativ kann ein anderer Pfad über `CONFIG_FILE` angegeben werden:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
CONFIG_FILE="/etc/docker-backup-sftp-uploader.conf" ./docker-backup-sftp-uploader.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
| Variable | Standard | Beschreibung |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `SFTP_HOST` | Pflichtwert | Hostname des SFTP-Servers |
|
||||||
|
| `SFTP_PORT` | `22` | Port des SFTP-Servers |
|
||||||
|
| `SFTP_USER` | Pflichtwert | SFTP-Benutzer |
|
||||||
|
| `SFTP_PASS` | Pflichtwert | SFTP-Passwort |
|
||||||
|
| `SFTP_REMOTE_DIR` | Pflichtwert | Zielverzeichnis auf dem SFTP-Server |
|
||||||
|
| `MAIL_TO` | leer | Empfängeradresse; leer deaktiviert Mailversand |
|
||||||
|
| `MAIL_FROM` | leer | Optionaler Absender für `mail -r` |
|
||||||
|
| `BACKUP_DIR` | leer = Ordner neben dem Projekt | Lokales Ziel für Archive |
|
||||||
|
| `LOG_DIR` | `${BACKUP_DIR}/logs` | Lokales Ziel für Logs |
|
||||||
|
| `KEEP_LOCAL_BACKUP` | `false` | Lokales Archiv nach Lauf behalten |
|
||||||
|
| `MIN_FREE_MB` | `1024` | Zusätzlicher freier Speicher, der neben der Quellgröße vorhanden sein muss |
|
||||||
|
|
||||||
|
## Voraussetzungen
|
||||||
|
|
||||||
|
Auf dem Server müssen diese Kommandos verfügbar sein:
|
||||||
|
|
||||||
|
- `docker`
|
||||||
|
- `tar`
|
||||||
|
- `gzip`
|
||||||
|
- `sshpass`
|
||||||
|
- `sftp`
|
||||||
|
- optional `mail`
|
||||||
|
|
||||||
|
## Mailversand
|
||||||
|
|
||||||
|
Das Script nutzt das lokale Kommando `mail`. Auf Debian/Ubuntu kann dafür zum Beispiel `mailutils`, `bsd-mailx` oder ein passendes Mail-Relay wie `msmtp` eingerichtet sein.
|
||||||
|
|
||||||
|
Wenn keine Mail ankommt:
|
||||||
|
|
||||||
|
- prüfen, ob `MAIL_TO` gesetzt ist
|
||||||
|
- prüfen, ob `mail` installiert ist: `command -v mail`
|
||||||
|
- einen manuellen Test ausführen: `echo test | mail -s "Test" empfaenger@example.com`
|
||||||
|
- lokale Mail-Logs prüfen, zum Beispiel `/var/log/mail.log`
|
||||||
|
- falls `MAIL_FROM` Probleme macht, testweise leer lassen
|
||||||
|
|
||||||
|
## Speicherplatz und große Dateien
|
||||||
|
|
||||||
|
Das Archiv wird bewusst nicht in `/tmp` erstellt, weil `/tmp` auf vielen Systemen als kleiner tmpfs-Mount eingerichtet ist. Für große Projekte sollte `BACKUP_DIR` auf ein Dateisystem mit ausreichend freiem Speicher zeigen, zum Beispiel:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
BACKUP_DIR="/srv/backups/mein-projekt"
|
||||||
|
```
|
||||||
|
|
||||||
|
Das Script prüft vor dem Docker-Stopp grob, ob genug Platz vorhanden ist. Der Mindestbedarf entspricht ungefähr der Quellgröße plus 10 Prozent Reserve plus `MIN_FREE_MB`.
|
||||||
|
|
||||||
|
Der SFTP-Upload schreibt zuerst `${BACKUP_FILE}.part` und benennt die Datei nach erfolgreichem Upload um. Dadurch bleibt auf dem Zielserver erkennbar, ob ein Upload vollständig abgeschlossen wurde.
|
||||||
|
|
||||||
|
## Cron-Beispiel
|
||||||
|
|
||||||
|
```cron
|
||||||
|
0 3 * * * /pfad/zum/docker-backup-sftp-uploader.sh
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user