Docker Persistent Storage: Volumes, Backups, Restore und Migration
AI generated
Docker · Storage · Backup · Migration · DevOps
Docker Persistent Storage:
Volumes, Backups, Restore und Migration

Container sind flüchtig – Daten dürfen es nicht sein. Wer Docker Persistent Storage mit Named Volumes, Backup-Automationen und klaren Restore-Verfahren aufbaut, verhindert Datenverlust und macht Host-Migrationen zu einem kontrollierbaren Vorgang statt einem Notfallszenario.

15 Min. Lesezeit Named Volumes · Bind Mounts · Backup · Restore · Migration Docker 24+ · Docker Compose · Linux

1. Warum Docker Persistent Storage unverzichtbar ist

Das fundamentale Merkmal eines Docker-Containers ist seine Flüchtigkeit: Wenn ein Container gestoppt, neu gestartet oder gelöscht wird, verschwinden alle Daten, die in seinem schreibbaren Container-Layer gespeichert wurden. Für zustandslose Anwendungen ist das kein Problem. Für Datenbanken, Medien-Uploads, Konfigurationsdateien und Sitzungsdaten bedeutet es jedoch Datenverlust – es sei denn, Docker Persistent Storage ist von Anfang an korrekt konfiguriert. Ohne persistente Speicherung ist ein Container-Deployment für produktive Workloads schlicht nicht geeignet.

Docker Persistent Storage entkoppelt die Datenhaltung vom Container-Lebenszyklus. Volumes, Bind Mounts und tmpfs-Mounts sind die drei Mechanismen, die Docker dafür bereitstellt. Jeder dieser Typen hat seinen Anwendungsfall, seine Stärken und seine Grenzen. Ein gut durchdachtes Storage-Design berücksichtigt nicht nur den normalen Betrieb, sondern auch Backup-Routinen, Disaster-Recovery und die Möglichkeit, Daten zwischen Hosts zu verschieben – ohne Ausfallzeiten oder Datenverlust. Docker Persistent Storage ist damit eine der wichtigsten Architekturentscheidungen im Container-Umfeld.

2. Storage-Typen: Named Volumes, Bind Mounts und tmpfs

Named Volumes sind die empfohlene Form von Docker Persistent Storage für Produktionsumgebungen. Docker verwaltet sie vollständig: Sie liegen standardmäßig unter /var/lib/docker/volumes/, sind unabhängig vom Dateisystem des Hosts und können von mehreren Containern gleichzeitig gemountet werden. Named Volumes überleben den Lebenszyklus eines Containers und bleiben auch nach einem docker rm erhalten. Sie können benannt, inspiziert, gesichert und auf andere Hosts übertragen werden – das macht sie zum Rückgrat jeder ernsthaften Docker Persistent Storage-Strategie.

Bind Mounts verknüpfen ein Verzeichnis des Hosts direkt mit einem Pfad im Container. Das ist praktisch für die Entwicklung, wo Quellcode live im Container verfügbar sein soll, ohne dass ein Image neu gebaut werden muss. Im Produktionsbetrieb bringen Bind Mounts jedoch Nachteile: Berechtigungen zwischen Host und Container können kollidieren, der Pfad muss auf dem Host existieren, und die Portierbarkeit leidet. tmpfs-Mounts schreiben Daten in den RAM des Hosts und eignen sich ausschließlich für temporäre, sicherheitskritische Daten wie Secrets oder Session-Tokens, die nach dem Container-Ende nicht auf die Festplatte persistiert werden sollen.

3. Named Volumes korrekt anlegen und verwalten

Ein Named Volume lässt sich mit docker volume create explizit anlegen oder wird automatisch erstellt, wenn ein Container auf ein bisher nicht existierendes Volume verweist. Die explizite Erstellung ist im Produktionsbetrieb vorzuziehen, weil sie Tippfehler im Volume-Namen sofort als Fehler ausweist statt lautlos ein neues, leeres Volume zu erzeugen. Mit docker volume inspect <name> lassen sich Mountpoint, Treiber und Labels eines Volumes abrufen. Labels helfen dabei, Volumes thematisch zu gruppieren und in Backup-Skripten nach bestimmten Kriterien zu filtern.

Verwaiste Volumes – solche, die keinem laufenden oder gestoppten Container mehr zugeordnet sind – können mit docker volume prune bereinigt werden. Dabei ist Vorsicht geboten: Der Befehl löscht alle nicht verwendeten Volumes unwiderruflich. In Produktionsumgebungen empfiehlt sich eine Label-basierte Strategie, bei der wichtige Volumes mit einem Label wie backup=required markiert werden, um sie von der automatischen Bereinigung auszunehmen. Docker Persistent Storage erfordert aktives Lifecycle-Management – Volumes akkumulieren sich sonst unkontrolliert und verbrauchen Plattenplatz.


# Create named volumes with labels for lifecycle management
docker volume create \
  --label app=magento \
  --label backup=required \
  --label env=production \
  magento_media

docker volume create \
  --label app=magento \
  --label backup=required \
  magento_db_data

# Inspect volume details (mountpoint, driver, labels)
docker volume inspect magento_db_data

# List volumes filtered by label
docker volume ls --filter label=backup=required

# Remove only dangling volumes (not labeled ones)
docker volume prune --filter label!=backup=required

# Show disk usage per volume
docker system df -v | grep -A 20 "Local Volumes"

4. Persistent Storage in Docker Compose konfigurieren

In Docker Compose werden persistente Volumes im Top-Level-Schlüssel volumes: deklariert und in den Service-Definitionen referenziert. Wenn ein Volume mit external: true markiert wird, erwartet Compose, dass es bereits existiert – Compose erstellt es nicht und bricht mit einem Fehler ab, wenn es fehlt. Das ist das bevorzugte Muster für Produktionsdaten: Der Operator legt das Volume bewusst an, füllt es gegebenenfalls vor, und Compose verwendet es. Ohne external: true würde ein docker compose down -v das Volume löschen – ein fataler Fehler, wenn er versehentlich auf dem Produktionssystem ausgeführt wird.

Mehrere Services können dasselbe Volume einbinden. Dabei sind die Mount-Modi ro (read-only) und rw (read-write) wichtig: Ein Webserver, der Medien nur ausliefert, sollte das Media-Volume nur im Lesemodus einbinden. So wird verhindert, dass ein kompromittierter Web-Prozess Dateien im Storage verändern kann. Subpath-Mounts erlauben es, nur einen Unterordner eines Volumes in einen bestimmten Container einzubinden – das reduziert die Angriffsfläche und verbessert die Trennung von Zuständigkeiten in Multi-Service-Setups.


# docker-compose.yml — Persistent storage with external volumes
# Run first: docker volume create --label backup=required magento_db_data

services:
  db:
    image: mysql:8.0
    volumes:
      - magento_db_data:/var/lib/mysql:rw
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password

  app:
    image: magento:2.4
    volumes:
      - magento_media:/var/www/html/pub/media:rw
      - magento_media:/var/www/html/pub/static:rw

  nginx:
    image: nginx:alpine
    volumes:
      # Read-only mount — nginx only serves, never writes
      - magento_media:/var/www/html/pub/media:ro

volumes:
  magento_db_data:
    external: true   # Must exist before compose up — prevents accidental creation
  magento_media:
    external: true

5. Automatisierte Backup-Strategien für Volumes

Das kanonische Muster für Volume-Backups in Docker ist ein kurzlebiger Container, der das zu sichernde Volume einbindet und seinen Inhalt als tar-Archiv in ein Backup-Verzeichnis schreibt. Dieser Container muss während des Backups nicht der einzige sein, der das Volume einbindet – er schreibt aber nichts zurück. Für Datenbanken ist ein konsistentes Backup komplexer: MySQL-Daten sollten nicht mit einem einfachen tar gesichert werden, solange der MySQL-Server läuft. Entweder wird der Service kurz gestoppt, oder ein Dump-Tool wie mysqldump oder mariadb-dump erzeugt ein transaktionskonsistentes Backup.

Automatisierte Backups lassen sich mit Cron auf dem Host oder mit einem dedizierten Backup-Container umsetzen. Ein Backup-Container, der mit einem Cron-Daemon läuft und Zugriff auf alle relevanten Volumes hat, kann Backups nach S3, zu einem NFS-Server oder auf eine externe Festplatte schreiben. Wichtig ist die Retention-Policy: Backups müssen nach einer definierten Aufbewahrungszeit rotiert werden, sonst füllt sich der Speicher. Das Muster mit Datumsstempeln im Dateinamen und einem Bereinigungsskript, das Dateien älter als N Tage löscht, ist einfach und zuverlässig. Docker Persistent Storage-Backups ohne Retention-Policy erzeugen langfristig Speicherprobleme.


#!/usr/bin/env bash
# backup-volumes.sh — Automated Docker volume backup with retention

set -euo pipefail

BACKUP_DIR="/srv/backups/docker"
RETENTION_DAYS=14
TIMESTAMP=$(date +%Y%m%d-%H%M%S)

mkdir -p "$BACKUP_DIR"

backup_volume() {
  local volume_name="$1"
  local archive="${BACKUP_DIR}/${volume_name}_${TIMESTAMP}.tar.gz"

  echo "[INFO] Backing up volume: $volume_name"

  # Spin up a temporary Alpine container to tar the volume contents
  docker run --rm \
    --volume "${volume_name}:/data:ro" \
    --volume "${BACKUP_DIR}:/backup:rw" \
    alpine:3 \
    tar -czf "/backup/${volume_name}_${TIMESTAMP}.tar.gz" -C /data .

  echo "[OK] Created: $archive"
}

# Backup MySQL via dump (consistent snapshot while server is running)
backup_mysql() {
  local volume_name="magento_db_data"
  local dump_file="${BACKUP_DIR}/mysql_dump_${TIMESTAMP}.sql.gz"

  docker exec magento_db_1 \
    mysqldump --single-transaction --quick --lock-tables=false \
    -u root --password="${MYSQL_ROOT_PASSWORD}" magento \
    | gzip -9 > "$dump_file"

  echo "[OK] MySQL dump: $dump_file"
}

# Backup all labeled volumes
while IFS= read -r volume; do
  backup_volume "$volume"
done < <(docker volume ls --filter label=backup=required --format '{ {.Name} }')

backup_mysql

# Rotate old backups — delete files older than RETENTION_DAYS
find "$BACKUP_DIR" -name "*.tar.gz" -mtime "+${RETENTION_DAYS}" -delete
find "$BACKUP_DIR" -name "*.sql.gz" -mtime "+${RETENTION_DAYS}" -delete

echo "[INFO] Backup complete. Retention: ${RETENTION_DAYS} days"

6. Daten sicher restoren: Schritt für Schritt

Ein Backup ohne erprobtes Restore-Verfahren ist kein Backup. Der Restore-Prozess für Docker Persistent Storage folgt immer derselben Sequenz: Service stoppen, Ziel-Volume leeren oder neu erstellen, Archiv entpacken, Service starten, Daten verifizieren. Das Stoppen des Services vor dem Restore ist entscheidend – werden Daten in ein Volume zurückgespielt, während ein Container schreibt, entstehen inkonsistente Zustände. Ein kurzes Wartungsfenster ist hier kein Luxus, sondern technische Notwendigkeit.

Für den Restore eines MySQL-Dumps wird der Dump in den laufenden Container gepipet, nachdem die Datenbank neu erstellt wurde. Das Verfahren unterscheidet sich vom Restore eines tar-Archivs, weil MySQL beim Start aus einem leeren Verzeichnis eine neue Datenbankstruktur anlegt – in die dann der Dump importiert wird. Wer ein tar-Archiv eines MySQL-Datenverzeichnisses zurückspielt, muss sicherstellen, dass die MySQL-Version identisch ist, weil das InnoDB-Format versionsspezifisch ist. Ein regelmäßiger Restore-Test in einer Staging-Umgebung ist die einzige Möglichkeit, die tatsächliche Wiederherstellbarkeit zu validieren.

7. Volumes zwischen Hosts migrieren

Die Migration von Docker Persistent Storage zwischen Hosts ist ein häufiger Vorgang bei Serverwechseln, Cloud-Umzügen oder beim Aufbau einer neuen Produktionsumgebung. Das grundlegende Verfahren: Volume auf dem Quell-Host als tar-Archiv exportieren, Archiv auf den Ziel-Host übertragen, dort in ein neues Volume importieren. Dieser Prozess ist für Named Volumes vollständig ohne Pfadanpassungen möglich, weil die Daten im Volume-Inhalt keine absoluten Hostpfade enthalten – im Gegensatz zu Bind Mounts, wo Hardlinks und absolute Pfade zum Problem werden können.

Bei der Live-Migration – also dem Umzug ohne oder mit minimalem Ausfallzeitraum – empfiehlt sich eine inkrementelle Strategie: Zunächst wird eine erste Vollsicherung übertragen, dann werden während einer kurzen Wartungsphase nur die Deltas übertragen. Für Datenbanken ist rsync oder scp auf das rohe Datenverzeichnis riskant; hier ist ein Dump und ein anschließender Import die sicherere Variante. Docker Persistent Storage-Migrationen sollten immer mit einem Pre-Migration-Backup und einer Post-Migration-Verifikation abgesichert werden.


#!/usr/bin/env bash
# migrate-volume.sh — Export volume from source, import on target host

set -euo pipefail

VOLUME_NAME="${1:?Usage: $0 <volume-name> <target-host>}"
TARGET_HOST="${2:?Usage: $0 <volume-name> <target-host>}"
ARCHIVE="/tmp/${VOLUME_NAME}_migrate_$(date +%Y%m%d%H%M%S).tar.gz"

echo "[INFO] Exporting volume: $VOLUME_NAME"

# Step 1: Export volume to compressed archive
docker run --rm \
  --volume "${VOLUME_NAME}:/data:ro" \
  alpine:3 \
  tar -czf - -C /data . > "$ARCHIVE"

echo "[OK] Exported to: $ARCHIVE ($(du -sh "$ARCHIVE" | cut -f1))"

# Step 2: Transfer archive to target host
echo "[INFO] Transferring to $TARGET_HOST ..."
scp "$ARCHIVE" "${TARGET_HOST}:/tmp/"

# Step 3: Create volume and import on target host
ssh "$TARGET_HOST" bash <<EOF
  set -euo pipefail
  docker volume create --label migrated=true --label source=$(hostname) "${VOLUME_NAME}"
  docker run --rm \
    --volume "${VOLUME_NAME}:/data:rw" \
    --volume "/tmp:/backup:ro" \
    alpine:3 \
    sh -c "cd /data && tar -xzf /backup/$(basename $ARCHIVE)"
  echo "[OK] Volume ${VOLUME_NAME} imported on \$(hostname)"
EOF

# Step 4: Cleanup local temp file
rm -f "$ARCHIVE"
echo "[INFO] Migration complete. Verify services on $TARGET_HOST before cutover."

8. Volume-Driver und externe Storage-Backends

Der Standard-Volume-Driver von Docker ist local, der Daten auf dem lokalen Dateisystem des Hosts speichert. Für verteilte Umgebungen, Multi-Host-Setups und Cloud-Deployments gibt es Volume-Plugins, die andere Storage-Backends anbinden: NFS-Shares, Amazon EBS, Azure Disk, GlusterFS oder Ceph. Mit dem local-Driver lässt sich ein NFS-Mount ebenfalls realisieren, indem die NFS-Mount-Optionen direkt in der Volume-Definition übergeben werden – ohne ein separates Plugin. Das ist praktisch für einfache Setups, bietet aber keine automatischen Failover- oder Replikationsfunktionen.

In Docker Swarm und Kubernetes ergibt sich die Frage nach Docker Persistent Storage auf einer anderen Ebene: Volumes müssen von jedem Node aus erreichbar sein, auf dem ein Container mit diesem Volume laufen könnte. Distributed Storage-Backends wie GlusterFS oder Ceph lösen das durch Replikation, bringen aber operationale Komplexität mit. Für kleine bis mittlere Deployments ist ein zentrales NFS-Backend mit regelmäßigen Backups oft die pragmatischere Lösung. Die Wahl des Storage-Backends ist eine der langfristigsten Entscheidungen beim Aufbau einer Container-Infrastruktur.

9. Storage-Typen im direkten Vergleich

Die drei Docker-Storage-Typen adressieren unterschiedliche Anforderungen. Die richtige Wahl hängt von Persistenz, Portierbarkeit, Backup-Fähigkeit und Performance-Anforderungen ab.

Kriterium Named Volume Bind Mount tmpfs Mount
Persistenz Ja, über Container-Lebenszyklus Ja, auf Host-Pfad Nein, nur im RAM
Portierbarkeit Hoch (kein Hostpfad) Niedrig (hostabhängig) Nicht relevant
Backup-fähig Ja, via docker run Ja, via Host-Tools Nein
Empfohlen für Produktion, Datenbanken Entwicklung, Config Secrets, Session-Tokens
Performance Gut (lokaler Driver) Sehr gut (direkter Mount) Optimal (RAM)

Named Volumes sind in fast allen Produktionsszenarien die richtige Wahl für Docker Persistent Storage. Bind Mounts haben ihren Platz in der lokalen Entwicklung, wo Quellcode live editiert und sofort im Container sichtbar sein soll. tmpfs-Mounts sind eine Spezialität für sicherheitssensible temporäre Daten. Die häufigste Fehlanwendung ist der Einsatz von Bind Mounts in Produktionsumgebungen für Daten, die regelmäßig gesichert werden müssen – hier sind Named Volumes die robustere Alternative.

Mironsoft

Docker Storage-Architekturen, Backup-Automatisierung und Migrations-Strategien

Docker Persistent Storage sicher aufbauen?

Wir konzipieren Volume-Strategien, automatisieren Backups mit Retention-Policy und begleiten Host-Migrationen – damit Produktionsdaten in Container-Umgebungen dauerhaft sicher sind.

Storage-Audit

Analyse bestehender Volume-Strategien und Identifikation von Datenverlust-Risiken

Backup-Automation

Vollständige Backup- und Restore-Skripte mit Retention, Alerting und Verifizierung

Host-Migration

Geplante Datenmigration mit minimalem Ausfallzeitraum und Post-Migration-Test

10. Zusammenfassung

Docker Persistent Storage ist keine optionale Ergänzung, sondern ein fundamentaler Bestandteil jeder Container-Architektur, die produktive Workloads betreibt. Named Volumes sind der empfohlene Mechanismus: portierbar, backup-fähig und unabhängig vom Container-Lebenszyklus. Bind Mounts haben ihren Platz in der Entwicklung, nicht in der Produktion. tmpfs-Mounts sind die richtige Wahl für kurzlebige, sicherheitssensible Daten im RAM. Die Kombination aus Labels, expliziter Volume-Erstellung, automatisierten Backups mit Retention-Policy und regelmäßigen Restore-Tests ergibt eine robuste Storage-Strategie.

Der wichtigste Grundsatz für Docker Persistent Storage im Produktionsbetrieb: Kein Volume ohne Backup-Routine, kein Backup ohne getestetes Restore-Verfahren. Die Migration zwischen Hosts mit dem tar-Export-Import-Muster ist zuverlässig und benötigt keine speziellen Tools. Volume-Driver für externe Storage-Backends wie NFS oder Cloud-Disks erweitern die Möglichkeiten für verteilte Umgebungen. Labels als Metadaten für Volumes ermöglichen gezieltes Backup-Management und verhindern versehentliche Löschungen durch docker volume prune.

Docker Persistent Storage — Das Wichtigste auf einen Blick

Named Volumes

Mit external: true in Compose schützen – verhindert versehentliches Löschen bei docker compose down -v. Labels für Backup-Management setzen.

Backup-Strategie

Kurzlebiger Alpine-Container für tar-Backups. MySQL via Dump sichern. Retention-Policy mit automatischer Rotation nach 14 Tagen implementieren.

Restore-Verfahren

Service stoppen, Volume leeren, Archiv entpacken, Service starten, Daten verifizieren. Regelmäßig in Staging testen – ein Backup ohne Restore-Test ist wertlos.

Host-Migration

tar-Export auf Quell-Host, scp/rsync auf Ziel-Host, Import via Alpine-Container. Pre-Migration-Backup und Post-Migration-Verifikation nicht auslassen.

11. FAQ: Docker Persistent Storage

1Was ist Docker Persistent Storage?
Alle Mechanismen, die Daten über den Container-Lebenszyklus hinaus erhalten: Named Volumes (Docker-verwaltet), Bind Mounts (Host-Pfad) und tmpfs-Mounts (nur RAM).
2Wo liegen Named Volumes auf dem Host?
Unter /var/lib/docker/volumes/<name>/_data. Genauer Pfad via docker volume inspect. Lieber kurzlebigen Container nutzen statt direkt zuzugreifen.
3Backup ohne Container-Stop?
Kurzlebiger Alpine-Container mit ro-Mount: docker run --rm -v vol:/data:ro alpine tar -czf - -C /data . Für Datenbanken mysqldump --single-transaction verwenden.
4Was passiert bei docker compose down?
Ohne -v bleiben Volumes erhalten. Mit -v werden alle Compose-Volumes gelöscht. external: true schützt Volumes vor Compose-seitigem Löschen – immer für Produktionsdaten verwenden.
5Volume auf anderen Host migrieren?
tar-Export, scp auf Ziel-Host, Import via Alpine-Container. Pre-Migration-Backup und Post-Migration-Verifikation nicht auslassen.
6Wann Bind Mounts statt Named Volumes?
Bind Mounts für lokale Entwicklung (Live-Code-Edit). In Produktion Named Volumes: portabler, backup-fähig, unabhängig von Host-Verzeichnissen.
7Volumes vor docker volume prune schützen?
Label setzen: docker volume create --label backup=required. Beim Prune filtern: docker volume prune --filter label!=backup=required.
8Named Volume vs. tmpfs?
Named Volume: persistiert dauerhaft auf Festplatte. tmpfs: nur RAM, nach Container-Ende weg. tmpfs für Secrets, Session-Tokens, temporäre Caches.
9Volume zwischen mehreren Containern teilen?
Ja, mehrere Container können dasselbe Volume einbinden (rw oder ro). Gleichzeitige Schreibzugriffe müssen von der Anwendung mit Locks koordiniert werden.
10Backup-Wiederherstellbarkeit testen?
Regelmäßige Restore-Tests in Staging: neues Test-Volume anlegen, Archiv einspielen, Daten inhaltlich prüfen. Backup ohne Restore-Test ist wertlos.