Persistente Datenverwaltung: Den richtigen Docker-Volumetyp wählen

Vergleiche Docker Named Volumes, Bind Mounts und tmpfs-Mounts für persistente Daten, Entwicklung und temporäre Speicherung.

Persistente Datenverwaltung: Den richtigen Docker-Volumetyp wählen

Docker-Container sind als austauschbar konzipiert. Daten, die in die beschreibbare Schicht des Containers geschrieben werden, überleben zwar einen einfachen Stop/Start, sind aber an diesen Container gebunden. Entfernt oder erstellt man den Container neu, sind diese Daten verloren. Das ist ein schlechter Ort für Datenbankdateien, hochgeladene Assets, Warteschlangen oder alles, dessen Verlust ärgerlich wäre.

Docker bietet drei gängige Mount-Optionen: Named Volumes, Bind Mounts und tmpfs-Mounts. Sie lösen unterschiedliche Probleme. Ein Produktions-Postgres-Container, ein lokaler Node.js-Entwicklungscontainer und ein temporäres Verzeichnis für vertrauliche Daten sollten nicht alle dasselbe Speichermuster verwenden.


Die Landschaft der Docker-Speichermechanismen

Docker kann Volume-Treiber für entfernte Speicher verwenden, aber die meisten alltäglichen Entscheidungen betreffen diese drei von der Docker-Engine oder dem Host-Kernel verwalteten Mount-Typen.

1. Named Volumes: Der Produktionsstandard

Named Volumes sind der bevorzugte Mechanismus für persistente Datenspeicherung in den meisten Produktionsumgebungen. Sie werden vollständig von der Docker-Engine verwaltet und abstrahieren den zugrunde liegenden Host-Dateisystempfad vom Benutzer.

Funktionen und Vorteile

  • Persistenz: Daten bleiben erhalten, auch wenn der Container, der sie erstellt hat, entfernt wird.
  • Portabilität: Die Containerdefinition hängt nicht von einem fest codierten Host-Pfad ab, was die Bereitstellung auf verschiedenen Maschinen erleichtert.
  • Verwaltung: Daten werden im Docker-Volume-Bereich gespeichert, normalerweise unter /var/lib/docker/volumes/ unter Linux. Sie verwalten es mit docker volume ls, docker volume inspect und Backup-Jobs.
  • Backup & Migration: Named Volumes lassen sich einfach sichern, wenn Sie einen Hilfscontainer, einen Dateisystem-Snapshot oder ein Backup auf Speicherebene verwenden. Für Datenbanken bevorzugen Sie datenbankbewusste Backup-Tools, wenn Konsistenz wichtig ist.

Anwendungsfälle

  • Datenbanken, wenn Sie auch einen echten Backup- und Wiederherstellungsprozess haben.
  • Anwendungsstatus und kritische Konfigurationsdateien.
  • Daten, die zwischen Containern auf demselben Host geteilt werden müssen.

Praxisbeispiel: Erstellen und Anhängen eines Named Volumes

# 1. Volume erstellen
docker volume create db_storage

# 2. Container ausführen und Volume am erforderlichen Pfad einhängen
docker run -d \
  --name postgres_db \
  -e POSTGRES_PASSWORD=securepass \
  --mount source=db_storage,target=/var/lib/postgresql/data \
  postgres:16

# 3. Volumedetails anzeigen
docker volume inspect db_storage

2. Bind Mounts: Lokale Entwicklung und Host-Interaktion

Bind Mounts ermöglichen es, eine beliebige Datei oder ein Verzeichnis vom Host-Rechner in einen Container zu映射. Im Gegensatz zu Named Volumes verlassen sich Bind Mounts vollständig auf die exakte Verzeichnisstruktur des Host-Rechners.

Funktionen und Einschränkungen

  • Sofortige Aktualisierungen: Der Hauptvorteil ist die Echtzeitsynchronisation. Änderungen auf dem Host (z.B. Aktualisieren von Code in Ihrer IDE) werden sofort im laufenden Container sichtbar, was sie ideal für Entwicklungsworkflows macht.
  • Nicht-Portabilität: Bind Mounts sind hostabhängig. Wenn der angegebene Host-Pfad auf einer anderen Maschine nicht existiert, kann Docker fehlschlagen oder je nach Syntax und Kontext ein Verzeichnis erstellen.
  • Berechtigungsprobleme: Besitzverhältnisse und Berechtigungen (UID/GID) verursachen oft Reibungen, insbesondere wenn Container als Nicht-Root-Benutzer ausgeführt werden. Der Container-Benutzer muss Lese-/Schreibberechtigungen für den Host-Pfad haben.
  • Sicherheitsrisiko: Das Freigeben von Host-Verzeichnissen kann gefährlich sein, wenn der Container-Prozess kompromittiert wird oder der Mount versehentlich beschreibbar ist.

Anwendungsfälle

  • Lokale Entwicklung: Quellcode für Live-Debugging oder Hot-Reloading einhängen.
  • Konfigurationsdateien: Spezifische Host-Konfiguration oder Anmeldeinformationen einspielen (z.B. /etc/timezone).
  • Zugriff auf Host-Ressourcen: Ein lokales Verzeichnis für Protokollierung oder Diagnose einhängen.

Praxisbeispiel: Entwicklungsworkflow

Einbinden des aktuellen Arbeitsverzeichnisses ($(pwd)) in den Anwendungsquellpfad im Container und als schreibgeschützt für Konfigurationsdateien festlegen.

# Aktuelles Verzeichnis für die Entwicklung einhängen
docker run -it --rm \
  --name dev_server \
  --mount type=bind,source=$(pwd)/src,target=/app/src \
  --mount type=bind,source=$(pwd)/config/app.conf,target=/etc/app/app.conf,readonly \
  node:22

Tipp: Verwenden Sie aus Gründen der Klarheit immer die --mount-Syntax (type=bind, source=..., target=...), insbesondere wenn Sie Volumetypen mischen, obwohl die kürzere -v-Syntax (/host/pfad:/container/pfad) für einfache Bind Mounts immer noch üblich ist.

3. Tmpfs-Mounts: Hochgeschwindigkeits-, nicht-persistenter Speicher

tmpfs-Mounts speichern Daten in speichergestütztem Speicher. Sie sind für viele temporäre Arbeitslasten schnell, aber die Daten werden nicht auf die Festplatte geschrieben. Wenn der Container stoppt oder das Host-System neu startet, sind die Daten weg.

Funktionen und Einschränkungen

  • Geschwindigkeit: Normalerweise schnell, da Daten im speichergestützten Speicher leben.
  • Nicht-Persistenz: Daten sind vollständig flüchtig. Nützlich für hochsensible Daten, die nicht auf der Festplatte verbleiben dürfen.
  • Ressourcenbeschränkung: Begrenzt durch den verfügbaren Arbeitsspeicher des Hosts. Nicht für große Datensätze geeignet.
  • Plattformumfang: tmpfs ist eine Linux-Funktion. Docker Desktop kann Linux-Container in einer VM ausführen, daher ist das Verhalten nicht dasselbe wie bei einem nativen Linux-Host.

Anwendungsfälle

  • Temporäre Sitzungsdateien oder Cache-Dateien, die sicher verschwinden können.
  • Caching-Mechanismen (z.B. temporäre Redis-Dateien).
  • Sicherheitskritische Vorgänge, bei denen Artefakte sofort nach der Ausführung vernichtet werden müssen.

Praxisbeispiel: Temporäre Dateien zwischenspeichern

# Container mit tmpfs für das /app/cache-Verzeichnis ausführen
docker run -d \
  --name fast_cache \
  --mount type=tmpfs,destination=/app/cache,tmpfs-size=512m \
  my_web_server:latest

Vergleichszusammenfassung und Entscheidungsmatrix

Die Wahl des richtigen Volumetyps hängt vollständig von den erforderlichen Persistenz-, Portabilitäts- und Zugriffsanforderungen ab.

Merkmal Named Volumes Bind Mounts Tmpfs-Mounts
Persistenz Hoch (von Docker verwaltet) Hoch (abhängig vom Host-Dateisystem) Keine (flüchtig, nur RAM)
Portabilität Hervorragend Schlecht (abhängig vom Host-Pfad) N/A (nur Linux-Hosts)
Leistung Normalerweise gut, abhängig vom zugrunde liegenden Speicher Variabel, abhängig vom Host-Pfad und Dateisystem-Sharing Normalerweise am schnellsten für temporäre I/O
Datenort Docker-internes Verzeichnis Bestimmtes Host-Verzeichnis Host-Arbeitsspeicher (RAM)
Verwaltung Docker-CLI-Tools (docker volume) Vom Host-Betriebssystem verwaltet Automatisch
Hauptanwendungsfall Produktionsdaten, Datenbanken, gemeinsam genutzter Speicher Lokale Entwicklung, Konfigurationseinspielung Caching, Sitzungsverwaltung, sichere temporäre Daten

Best Practices für die Datenverwaltung

Standardisierung des persistenten Speichers

Für die meisten Single-Host-Produktionscontainer, die Persistenz benötigen, sind Named Volumes die saubere Standardeinstellung. Sie vermeiden fest codierte Host-Pfade und erleichtern die Wiederverwendung von Containerdefinitionen. Verwenden Sie in orchestrierten Umgebungen das persistente Volumesystem der Plattform, anstatt davon auszugehen, dass ein lokales Docker-Volume ausreicht.

Umgang mit Dateiberechtigungen

Bei Bind Mounts sind Berechtigungskonflikte ein häufiges Problem. Wenn der Benutzer im Container versucht, in einen Volumepfad zu schreiben, der einem anderen Benutzer/einer anderen Gruppe auf dem Host gehört, schlägt der Vorgang fehl.

Stellen Sie sicher, dass der Benutzer im Container mit dem Besitzer der eingehängten Dateien übereinstimmt, oder passen Sie das Host-Verzeichnis gezielt an. Vermeiden Sie es, jedes Berechtigungsproblem mit einem Root-Container zu lösen; es funktioniert, bis es Root-gehörige Build-Artefakte auf einem Entwicklerrechner hinterlässt.

Verwenden Sie schreibgeschützte Mounts aus Sicherheitsgründen

Wenn Sie Konfigurationsdateien, statische Ressourcen oder Anmeldeinformationen einhängen, die der Container nicht ändern soll, geben Sie das Volume immer als schreibgeschützt an. Dies verhindert das versehentliche Löschen oder Ändern kritischer Dateien.

# Beispiel für einen schreibgeschützten Mount
docker run -d \
  --mount type=bind,source=/etc/my_key.pem,target=/app/key.pem,readonly \
  my_app

Vermeiden Sie Host-Root-Bind-Mounts

Es wird dringend empfohlen, das Binden sensibler oder großer Root-Verzeichnisse (z.B. -v /:/host) zu vermeiden. Diese Praxis schafft erhebliche Sicherheitslücken und kann die Containerverwaltung aufgrund unbeabsichtigter Nebenwirkungen instabil machen.

Volume-Bereinigung

Docker entfernt Named Volumes nicht automatisch, wenn Container entfernt werden. Anonyme Volumes können sich ebenfalls ansammeln, wenn Container wiederholt neu erstellt werden. Überprüfen Sie vor dem Bereinigen, insbesondere auf gemeinsam genutzten Hosts:

docker volume ls
docker system df -v

# Nicht verwendete lokale Volumes entfernen, nachdem Sie überprüft haben, dass sie nicht benötigt werden
docker volume prune

Backup und Wiederherstellung sollten die Wahl bestimmen

Der Mount-Typ ist nur die halbe Entscheidung. Die andere Hälfte ist, wie Sie die Daten an einem schlechten Tag wiederherstellen.

Für ein Named Volume, das normale Dateien speichert, kann ein Hilfscontainer ein Tar-Archiv erstellen:

docker run --rm \
  --mount source=db_storage,target=/data,readonly \
  --mount type=bind,source=$(pwd),target=/backup \
  alpine:3.20 \
  tar -czf /backup/db_storage.tar.gz -C /data .

Dieses Muster ist für statische Dateien oder gestoppte Dienste in Ordnung. Es reicht nicht für eine Live-Datenbank, es sei denn, die Datenbank befindet sich in einem konsistenten Zustand. Verwenden Sie für Postgres, MySQL, MongoDB und ähnliche Systeme datenbanknative Backup-Tools oder Speicher-Snapshots, die mit der Datenbank koordiniert werden. Ein Tarball eines laufenden Datenbankverzeichnisses kann wie ein Backup aussehen und bei der Wiederherstellung fehlschlagen.

Die Wiederherstellung eines Named Volumes ist der umgekehrte Ansatz:

docker volume create db_storage_restored
docker run --rm \
  --mount source=db_storage_restored,target=/data \
  --mount type=bind,source=$(pwd),target=/backup,readonly \
  alpine:3.20 \
  tar -xzf /backup/db_storage.tar.gz -C /data

Testen Sie dies, bevor Sie es brauchen. Eine Volumestrategie, die noch nie wiederhergestellt wurde, ist keine Strategie; es ist eine Vermutung.

Compose-Beispiele für reale Projekte

In Compose sind Named Volumes einfach und lesbar:

services:
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: example
    volumes:
      - db_data:/var/lib/postgresql/data

volumes:
  db_data:

Für die lokale Entwicklung sind Bind Mounts normalerweise besser, da Sie möchten, dass Quellcodeänderungen auf dem Host im Container sichtbar werden:

services:
  app:
    image: node:22
    working_dir: /app
    command: npm run dev
    volumes:
      - ./src:/app/src
      - ./package.json:/app/package.json:ro

Beachten Sie das schreibgeschützte Flag bei package.json. Es ist eine kleine Gewohnheit, verhindert aber, dass ein Container Dateien überschreibt, die er nur lesen sollte.

Für tmpfs in Compose:

services:
  worker:
    image: my-worker:latest
    tmpfs:
      - /run/secrets:size=64m

Verwenden Sie dies für temporäre Daten, nicht für etwas, das Sie nach einem Absturz untersuchen möchten.

Häufige Fehlermodi

Der häufigste Docker-Speicherfehler ist das Einhängen des falschen Pfads. Wenn die Anwendung nach /var/lib/mysql schreibt, das Image aber /var/lib/mysql/data erwartet, läuft der Container trotzdem und die Daten verschwinden, wenn Sie ihn neu erstellen. Bestätigen Sie immer die Image-Dokumentation und überprüfen Sie den laufenden Container:

docker inspect my_container --format '{{json .Mounts}}'

Ein weiterer häufiger Fehler ist die Verwechslung von anonymen Volumes mit Named Volumes. Wenn ein Image ein VOLUME deklariert und Sie kein Named Volume bereitstellen, kann Docker ein anonymes erstellen. Die Daten bleiben erhalten, aber der Name ist nicht aussagekräftig, sodass sie bei der Bereinigung oder Migration übersehen werden.

Berechtigungen sind das nächste Problem. Wenn ein bind-gemountetes Verzeichnis unter macOS UID 501 oder unter Linux UID 1000 gehört, der Container-Prozess jedoch als UID 999 läuft, können Schreibvorgänge fehlschlagen. Named Volumes vermeiden oft Host-Pfad-Verwirrung, aber die Besitzverhältnisse innerhalb des Volumes sind immer noch wichtig. Initialisieren Sie die Besitzverhältnisse bewusst, anstatt Berechtigungen zu ändern, bis der Fehler verschwindet.

Denken Sie schließlich daran, dass lokale Docker-Volumes lokal sind. Sie folgen einem Container nicht von selbst auf einen anderen Host. In Swarm, Kubernetes, Nomad oder Cloud-Container-Plattformen benötigt persistenter Speicher plattformbewusste Volumes, entfernten Speicher oder einen für diese Umgebung ausgelegten Datenbankdienst.

Kennzeichnen Sie wichtige Volumes, wenn Ihre Toolchain dies unterstützt, und dokumentieren Sie, welcher Dienst welches Volume besitzt. Eine klare Eigentümerschaft verhindert, dass Bereinigungsskripte Daten löschen, die nur ungenutzt aussehen.

Eine einfache Entscheidungsregel

Wenn Sie unsicher sind, fragen Sie, wem die Daten gehören. Wenn Docker sie besitzt und der Host-Pfad nicht von Bedeutung ist, verwenden Sie ein Named Volume. Wenn ein Mensch oder ein externes Tool auf dem Host sie besitzt, verwenden Sie einen Bind Mount. Wenn niemand sie besitzen sollte, nachdem der Container beendet wurde, verwenden Sie tmpfs.

Diese Regel deckt die meisten Fälle ab. Ein Datenbankverzeichnis gehört dem Container, also passt ein Named Volume. Quellcode gehört dem Entwickler, also passt ein Bind Mount. Ein temporäres Entschlüsselungsverzeichnis für einen Job sollte verschwinden, also passt tmpfs. Die verwirrenden Fälle sind gemeinsam genutzte Uploads, Protokolle und generierte Berichte. Entscheiden Sie für diese, ob die Container-Plattform, der Host oder ein externer Speicherdienst der eigentliche Eigentümer ist, bevor Sie den Mount-Typ wählen.

Die Kurzversion lautet: Verwenden Sie Named Volumes für container-eigene persistente Daten, Bind Mounts, wenn der Host-Pfad selbst Teil des Workflows ist, und tmpfs für Daten, die schnell und wegwerfbar sein müssen. Notieren Sie dann, wie jedes wichtige Volume gesichert und wiederhergestellt wird. Persistenz ohne Wiederherstellungstest ist nur Hoffnung mit einem Mount-Punkt.