Station 01/Sicherung und Rückweg·Vorschau
Station 01 · Einrichten/Phase 4

Sicherung und Rückweg

Datenbank, Schlüssel, Abläufe. Fehlt eines davon, ist die Sicherung im Ernstfall wertlos — und das merkt man genau dann.

Der Film zu dieser Phase1:41 — mit Untertiteln. Er ersetzt den Text nicht, er geht ihm voraus.
Was gesichert wirdUnd die Probe, ohne die es keine Sicherung ist
EINE SICHERUNG, DIE NICHT ZURÜCKGESPIELT WURDE, IST KEINEDie DatenbankAbläufe, Zugänge, LäufetäglichDer SchlüsselN8N_ENCRYPTION_KEYeinmal, sicherDas VolumeDateien der AbläufetäglichDer ExportAbläufe als JSON im Repositorybei jeder ÄnderungDie Probe: einmal im Quartal auf einen leeren Container zurückspielenDatenbank einspielen, Schlüssel setzen, Container starten, einen Ablauf von Hand auslösen.Erst wenn der durchläuft, ist die Sicherung eine.Der häufigste Fehler: Die Datenbank wird gesichert, der Schlüssel nicht.Beim Zurückspielen ist dann jeder Zugang unbrauchbar und muss neu eingetragen werden — im Ernstfall unter Zeitdruck.

Der Befehl

täglich, am besten als Zeitplan in Coolify
sudo bash automatisierung/n8n-sichern.sh
# zusätzlich verschlüsselt:
sudo bash automatisierung/n8n-sichern.sh --passwort

Das Skript legt Umgebung (mit Schlüssel), Datenbankabzug, alle Abläufe als JSON und eine Wiederherstellungsanleitung in eine Datei. Was es nicht sichert, sind die Daten der Fremdsysteme — Postfach, Anwendungsdatenbank, Dateiablagen. Die haben ihre eigene Sicherung.

Das Sicherungsskript zum Mitlesen n8n-sichern.sh 154 Zeilen — Kopierknopf oben rechts
n8n-sichern.sh
#!/usr/bin/env bash
#
# n8n-sichern.sh — Datenbank, Schlüssel und Abläufe in eine Datei.
#
# n8n verschlüsselt alle hinterlegten Zugänge mit einem einzigen Schlüssel:
# N8N_ENCRYPTION_KEY. Wer die Datenbank sichert, diesen Schlüssel aber nicht,
# hat eine Sicherung, die sich nicht mehr öffnen lässt — die Daten sind
# vorhanden und unlesbar. Deshalb legt dieses Skript beides zusammen.
#
#   sudo bash n8n-sichern.sh
#   sudo bash n8n-sichern.sh --passwort              (zusätzlich verschlüsselt)
#   sudo bash n8n-sichern.sh --ziel /root/umschlag.tar.gz --leise
#
# Es ändert nichts an der laufenden Installation und liest nur.
# Der Umschlag gehört VOM SERVER HERUNTER — sonst ist er im Ernstfall
# genau dort, wo er nicht mehr erreichbar ist.

set -Eeuo pipefail

VERZEICHNIS="/opt/n8n"
ZIEL=""
VERSCHLUESSELN=0
LEISE=0
BEHALTEN=14        # so viele Sicherungen bleiben im Verzeichnis liegen

if [[ -t 1 ]]; then
  F_OK=$'\e[32m'; F_WARN=$'\e[33m'; F_LEISE=$'\e[2m'; F_AUS=$'\e[0m'
else
  F_OK=""; F_WARN=""; F_LEISE=""; F_AUS=""
fi
ok()      { (( LEISE )) || printf '  %s✓%s %s\n' "$F_OK" "$F_AUS" "$1"; }
info()    { (( LEISE )) || printf '  %s·%s %s\n' "$F_LEISE" "$F_AUS" "$1"; }
warnung() { printf '  %s!%s %s\n' "$F_WARN" "$F_AUS" "$1" >&2; }
abbruch() { printf '\n✗ %s\n  Nächster Schritt: %s\n\n' "$1" "$2" >&2; exit 1; }

while [[ $# -gt 0 ]]; do
  case "$1" in
    --verzeichnis) VERZEICHNIS="${2:?}"; shift 2 ;;
    --ziel)        ZIEL="${2:?}"; shift 2 ;;
    --passwort)    VERSCHLUESSELN=1; shift ;;
    --leise)       LEISE=1; shift ;;
    -h|--hilfe|--help) sed -n '2,17p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
    *) abbruch "Unbekannte Angabe: $1" "bash $0 --hilfe" ;;
  esac
done

COMPOSE="${VERZEICHNIS}/docker-compose.yml"
UMGEBUNG="${VERZEICHNIS}/.env"
[[ -f "$COMPOSE" ]]  || abbruch "${COMPOSE} fehlt." "Verzeichnis angeben: --verzeichnis /pfad/zu/n8n"
[[ -r "$UMGEBUNG" ]] || abbruch "${UMGEBUNG} nicht lesbar." "Mit sudo ausführen."

STAND="$(date '+%Y-%m-%d_%H%M')"
ORDNER="${VERZEICHNIS}/sicherung"
[[ -n "$ZIEL" ]] || ZIEL="${ORDNER}/n8n-${STAND}.tar.gz"
mkdir -p "$ORDNER"

ARBEIT="$(mktemp -d)"
trap 'rm -rf "$ARBEIT"' EXIT
PAKET="${ARBEIT}/n8n-${STAND}"
mkdir -p "$PAKET"

dc() { docker compose -f "$COMPOSE" "$@"; }
umg() { grep -E "^${1}=" "$UMGEBUNG" | head -1 | cut -d= -f2-; }

# 1 · Der Schlüssel und die Umgebung
cp "$UMGEBUNG" "${PAKET}/umgebung.env"
chmod 600 "${PAKET}/umgebung.env"
ok "Umgebung samt Verschlüsselungsschlüssel übernommen"

# 2 · Die Datenbank
DBID="$(dc ps -q db 2>/dev/null | head -1)"
if [[ -n "$DBID" ]]; then
  if docker exec "$DBID" pg_dump -U "$(umg POSTGRES_USER)" -d "$(umg POSTGRES_DB)" \
       > "${PAKET}/datenbank.sql" 2>/dev/null; then
    ok "Datenbank gesichert ($(du -h "${PAKET}/datenbank.sql" | cut -f1))"
  else
    warnung "pg_dump fehlgeschlagen — Sicherung ist unvollständig"
  fi
else
  warnung "Datenbank-Container läuft nicht — keine Datenbanksicherung"
fi

# 3 · Die Abläufe als lesbare Dateien (ohne Zugangsdaten)
N8NID="$(dc ps -q n8n 2>/dev/null | head -1)"
if [[ -n "$N8NID" ]]; then
  mkdir -p "${PAKET}/ablaeufe"
  if docker exec "$N8NID" n8n export:workflow --all --pretty --separate --output=/ablaeufe/ >/dev/null 2>&1; then
    cp -r "${VERZEICHNIS}/ablaeufe/." "${PAKET}/ablaeufe/" 2>/dev/null || true
    ok "Abläufe als JSON gesichert ($(find "${PAKET}/ablaeufe" -name '*.json' | wc -l | tr -d ' ') Dateien)"
    info "Zugangsdaten sind darin NICHT enthalten — sie stehen verschlüsselt in der Datenbank."
  else
    warnung "Export der Abläufe fehlgeschlagen — die Datenbanksicherung enthält sie trotzdem"
  fi
fi

# 4 · Anleitung zum Zurückspielen
cat > "${PAKET}/ANLEITUNG.txt" <<TXT
Wiederherstellung — n8n, Stand ${STAND}

Voraussetzung: ein Server mit Docker, wie in Kurs 1 aufgesetzt.

1. Verzeichnis anlegen und diese Dateien hineinlegen:
     mkdir -p /opt/n8n && cd /opt/n8n

2. Umgebung zurückspielen — MIT dem alten Verschlüsselungsschlüssel:
     cp umgebung.env /opt/n8n/.env && chmod 600 /opt/n8n/.env
   Ein anderer Schlüssel macht alle hinterlegten Zugänge unlesbar.
   Das ist der häufigste Fehler beim Zurückspielen.

3. docker-compose.yml aus dem Repository holen (oder n8n-aufsetzen.sh laufen
   lassen — es lässt eine bestehende .env unangetastet).

4. Nur die Datenbank starten und den Abzug einspielen:
     docker compose up -d db
     docker compose exec -T db psql -U n8n -d n8n < datenbank.sql

5. n8n starten und anmelden:
     docker compose up -d

6. Die Probe: einen Ablauf von Hand auslösen und im Protokoll nachsehen,
   ob er durchläuft. Erst dann war die Sicherung eine.

Was NICHT in diesem Paket ist: die Daten der Fremdsysteme (Postfach,
Datenbank der Anwendung, Dateiablagen). Die haben ihre eigene Sicherung.
TXT

# 5 · Einpacken
tar -czf "${ARBEIT}/paket.tar.gz" -C "$ARBEIT" "n8n-${STAND}"
if (( VERSCHLUESSELN )); then
  command -v openssl >/dev/null || abbruch "openssl fehlt." "Ohne --passwort erneut ausführen."
  openssl enc -aes-256-cbc -pbkdf2 -salt -in "${ARBEIT}/paket.tar.gz" -out "${ZIEL}.enc"
  ZIEL="${ZIEL}.enc"
else
  mv "${ARBEIT}/paket.tar.gz" "$ZIEL"
fi
chmod 600 "$ZIEL"
ok "Sicherung liegt hier: ${ZIEL} ($(du -h "$ZIEL" | cut -f1))"

# 6 · Alte Sicherungen aufräumen
ANZAHL="$(ls -1t "${ORDNER}"/n8n-*.tar.gz* 2>/dev/null | wc -l | tr -d ' ')"
if (( ANZAHL > BEHALTEN )); then
  ls -1t "${ORDNER}"/n8n-*.tar.gz* | tail -n +$((BEHALTEN+1)) | xargs -r rm -f
  info "Alte Sicherungen entfernt — die letzten ${BEHALTEN} bleiben liegen"
fi

(( LEISE )) || cat <<TXT

  Der wichtigste Schritt fehlt noch: die Datei vom Server holen.
    scp betreiber@$(umg DOMAIN 2>/dev/null || hostname):${ZIEL} ~/Desktop/

  Und einmal im Quartal: auf einen leeren Container zurückspielen.
  Eine Sicherung, die nicht zurückgespielt wurde, ist keine.

TXT

Die Probe — einmal im Quartal

1

Einen leeren Container nehmen

Ein zweiter Server, eine zweite Maschine, ein leeres Verzeichnis. Nicht der laufende — es geht darum, ob die Sicherung allein trägt.

2

Umgebung zurückspielen — mit dem alten Schlüssel

Das ist die Stelle, an der es schiefgeht. Ein anderer Verschlüsselungsschlüssel macht jeden hinterlegten Zugang unlesbar; n8n meldet dann bei jedem Ablauf „credentials could not be decrypted".

3

Datenbank einspielen und starten

auf dem Ersatzserver
docker compose up -d db
docker compose exec -T db psql -U n8n -d n8n < datenbank.sql
docker compose up -d
4

Einen Ablauf von Hand auslösen

Läuft er durch, war die Sicherung eine. Läuft er nicht, haben Sie es an einem Dienstagvormittag gemerkt und nicht im Ernstfall.

Der häufigste Fehler in der Praxis: Die Datenbank wird täglich gesichert, der Schlüssel nie. Beim Zurückspielen ist dann jeder Zugang neu einzutragen — Datenbank, Postfach, jedes Fremdsystem, unter Zeitdruck, oft ohne die Kennwörter zur Hand.
  • Prüfliste Sicherung
Zugang erhalten
Fortschritt merken?Mit Zugang bleiben Häkchen und erledigte Phasen am Konto — auf jedem Gerät.