Begriff
Docker Compose Volumes
Warum wichtig?
Dieser Begriff ist ein Knoten im SengakujiWorks-Wissensnetz. Nutze Level 0 für die erste Einordnung, Level 1 für Praxis, Level 2 für technische Struktur und Level 3 für Grenzen, Fallstricke und Expertenkontext.
In docker-compose.yml definierst du, wo deine Daten überleben.
Wenn du eine Datenbank (postgres) startest und den Container löschst, sind die Daten weg.
Das ist schlecht.
Mit Volumes sagst du: "Speichere /var/lib/postgresql/data an einem sicheren Ort auf dem Host."
Docker Compose hat zwei Arten:
- Short Syntax:
- ./data:/db. (Einfach, Bind Mount). - Long Syntax / Named Volumes: Sauberer, von Docker verwaltet.
Merksatz: Die Konfiguration von persistentem Speicher innerhalb von Docker Compose, um Daten unabhängig vom Lebenszyklus der Container zu bewahren.
Named Volumes (Empfohlen für DBs):
services:
db:
image: mysql
volumes:
- db_data:/var/lib/mysql
volumes:
db_data: # Muss hier definiert werden!
Docker erstellt ein Volume projektname_db_data. Die Daten liegen tief in /var/lib/docker/volumes. Sie überleben docker compose down.
Löschen erzwingen: docker compose down -v.
Bind Mounts (Empfohlen für Configs/Code):
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
Nutze relative Pfade (./). :ro macht es Read-Only (Sicherheit).
Praxisroutine
In der Praxis lernst du Docker Compose Volumes, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
1. Volume Drivers (NFS / Cloud)
Volumes müssen nicht lokal sein. Du kannst Plugins nutzen:
volumes:
cloud_storage:
driver: rexray/s3
driver_opts:
bucket: my-bucket
Der Container schreibt lokal, der Treiber schiebt es nach S3.
Oder local-persist für festes Mounten von NFS-Shares.
Das erlaubt Containern, zwischen Hosts zu wandern (Swarm/K8s Vorstufe).
2. Copy-on-Write Init
Ein geniales Feature von Docker Volumes:
Wenn das Image in /app/data schon Dateien hat (z. B. eine Default-Config) und du ein leeres Volume drüber mountest...
...kopiert Docker den Inhalt vom Image in das Volume.
Bei Bind Mounts passiert das nicht (der Ordner wird überdeckt/leer).
Das macht Named Volumes sehr anfängerfreundlich ("Pre-Seeding Data").
3. Permissions & User Mapping
Klassisches Problem:
Datenbank schreibt als User postgres (UID 999).
Du machst Backup und startest neue DB. Die hat UID 70.
"Permission Denied".
Docker kennt keine UIDs im Volume-Metadaten.
Lösung: Nutzung von initContainers (chown -R 999 /data) beim Start, um Rechte zu fixen.
1. Inode Replacement und die Bind-Mount Falle
Ein Bind Mount (- ./app:/app) verzahnt ein Host-Verzeichnis in den Container.
Problem beim Coding: Du mountest eine Einzeldatei (- ./config.yaml:/app/config.yaml).
Wenn deine lokale IDE die Datei config.yaml überschreibt, tun viele Texteditoren dies per Atomic Save "Safe Write"-Mechanismus: Sie schreiben eine config.tmp, löschen die echte config.yaml und benennen die tmp heimlich um. Dadurch ändert sich die Inode (Nummer auf der Festplatte). Docker jedoch trackt den Bind-Mount starr auf die alte Inode. Plötzlich "updatet" der Container Änderungen nicht mehr, weil der Linux-Kernel den alten Pointer zu einer abgeklemmten Schatten-Inode führt. Deswegen sollte man niemals Einzeldateien mounten, sondern immer ihr übergeordnetes Verzeichnis (Directory), da der Inode des Ordners stabil bleibt.
2. Die Anonyme Volume-Kette
Wenn im offiziellen Dockerfile einer Datenbank ein Kommando wie VOLUME /var/lib/mysql hardcodiert ist, erstellt der Docker Engine bei jedem simplen docker run ein sogenanntes Anonymes Volume (ein Ordner im Host mit einem 64-stelligen UUID-Hash wie 8f2dca...), falls der User kein Named Volume spezifiziert hat.
Zerstörst du den Container (docker rm), bleibt dieser Hash-Order oft unlöschbar und unsichtbar (verwaist) im Laufwerk zurück, bis /var/lib/docker/volumes die gesamte SSD (Solid State Drive) frisst. Deshalb erzwingt man Named Volumes (mysql_data:/var/lib...) im Compose. Die Aufräumung verwaister Kacheln erfolgt per hartem docker volume prune.
3. Chowning beim Mount vs. Init-Scripts
Mountet man ein persistentes Datenbank/Named Volume auf einen Linux-Host, gehört das Volume (da vom Daemon generiert) fast immer root:root.
Läuft dein Express/Node.js Container jedoch sauber als ungehinderter Unprivileged User (z.B. User uid=1000 node), prallt der Container mit einem harten Permission Denied Error 13 vom Mountpunkt ab und crasht.
In Docker Compose fixen das Sysadmins durch Workarounds: Entweder ein Entrypoint-Shellscript im Container ausführen, welches als kurzes root via chown -R 1000:1000 /app/data die Zugriffsrechte ins Volume hämmert und dann mit su-exec node /bin/app das Zepter aufgibt, oder (moderner, ab Compose v2.22) durch das definieren dedizierter --userns-remap Namensumbelegungen durch den Daemon.
Quick-Check
Was ist
tmpfs?Ein Volume im RAM.- type: tmpfs, target: /tmp. Daten sind weg beim Neustart. Extrem schnell. Gut für Cache oder Security-Keys, die niemals auf die Festplatte geschrieben werden sollen.Unterschied
volumevs.bindin Long Syntax?Die Long Syntax (type: bind) ist expliziter. Sie erstellt den Ordner nicht automatisch, wenn er fehlt (Error), was gut ist, um Tippfehler zu finden. Short Syntax erstellt einfach leere Ordner.Wie migriere ich Volumes?
Schwer. "Docker cp" geht nicht gut bei Volumes. Best Practice: Starte einen temporären Container, der das Volume UND einen lokalen Ordner mountet, und machetar cvf. Oder nutze Backup-Tools.