Docker (Auto)Backup mit Time Machine

Nachfolgend eine praxisbewährte, macOS-konforme Lösung bestehend aus

  1. einem Shell-Skript, das

    • alle laufenden Docker-Container stoppt

    • ein Time-Machine-Backup anstößt

    • nach erfolgreichem Backup alle zuvor laufenden Container wieder startet

  2. einer launchd-Konfiguration, um das Skript einmal täglich automatisch auszuführen.

Die Lösung ist bewusst defensiv aufgebaut (Logging, Fehlerbehandlung, reproduzierbarer Zustand).


1. Backup-Skript

Datei: /usr/local/bin/timemachine_docker_backup.sh

#!/bin/bash
set -euo pipefail

LOGFILE=“/var/log/timemachine_docker_backup.log“
DATE=“$(date ‚+%Y-%m-%d %H:%M:%S‘)“

echo „[$DATE] Backup gestartet“ >> „$LOGFILE“

# Prüfen, ob Docker verfügbar ist
if ! command -v docker >/dev/null 2>&1; then
echo „[$DATE] Docker nicht gefunden – Abbruch“ >> „$LOGFILE“
exit 1
fi

# Laufende Container ermitteln
RUNNING_CONTAINERS=$(docker ps -q)

echo „[$DATE] Laufende Container: $RUNNING_CONTAINERS“ >> „$LOGFILE“

# Container stoppen
if [ -n „$RUNNING_CONTAINERS“ ]; then
docker stop $RUNNING_CONTAINERS >> „$LOGFILE“ 2>&1
echo „[$DATE] Container gestoppt“ >> „$LOGFILE“
else
echo „[$DATE] Keine laufenden Container“ >> „$LOGFILE“
fi

# Time Machine Backup starten (blockierend)
echo „[$DATE] Time Machine Backup gestartet“ >> „$LOGFILE“

/usr/bin/tmutil startbackup –auto –block >> „$LOGFILE“ 2>&1

echo „[$DATE] Time Machine Backup erfolgreich abgeschlossen“ >> „$LOGFILE“

# Container wieder starten
if [ -n „$RUNNING_CONTAINERS“ ]; then
docker start $RUNNING_CONTAINERS >> „$LOGFILE“ 2>&1
echo „[$DATE] Container wieder gestartet“ >> „$LOGFILE“
fi

echo „[$DATE] Backup-Prozess abgeschlossen“ >> „$LOGFILE“

Berechtigungen setzen

sudo chmod +x /usr/local/bin/timemachine_docker_backup.sh
sudo touch /var/log/timemachine_docker_backup.log
sudo chmod 644 /var/log/timemachine_docker_backup.log

2. Automatische tägliche Ausführung (launchd)

macOS verwendet launchd, nicht cron.

Datei: ~/Library/LaunchAgents/com.local.timemachine.dockerbackup.plist

<?xml version=“1.0″ encoding=“UTF-8″?>
<!DOCTYPE plist PUBLIC „-//Apple//DTD PLIST 1.0//EN“
„http://www.apple.com/DTDs/PropertyList-1.0.dtd“>
<plist version=“1.0″>
<dict>

<key>Label</key>
<string>com.local.timemachine.dockerbackup</string>

<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/timemachine_docker_backup.sh</string>
</array>

<!– Täglich um 02:00 Uhr –>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>2</integer>
<key>Minute</key>
<integer>0</integer>
</dict>

<key>StandardOutPath</key>
<string>/var/log/timemachine_docker_backup.log</string>

<key>StandardErrorPath</key>
<string>/var/log/timemachine_docker_backup.log</string>

<key>RunAtLoad</key>
<false/>

</dict>
</plist>

launchctl load ~/Library/LaunchAgents/com.local.timemachine.dockerbackup.plist

Job laden

launchctl load ~/Library/LaunchAgents/com.local.timemachine.dockerbackup.plist

Status prüfen

launchctl list | grep timemachine

Wichtige Hinweise

  • Das Skript verwendet tmutil startbackup --block, wodurch erst nach vollständig abgeschlossenem Backup fortgefahren wird.

  • Es werden nur die Container neu gestartet, die vor dem Backup tatsächlich liefen.

  • Docker Desktop muss beim Ausführungszeitpunkt bereits laufen.

  • Falls Sie FileVault oder Netzlaufwerke verwenden, sollte das Backup-Ziel beim Start verfügbar sein.