Wenn eine Anwendung in einem Container verpackt laufen soll, die dauerhaft Daten speichern möchte – bspw. eine Datenbank -, reicht es in aller Regel nicht aus, dafür das Container-interne Dateisystem zu nutzen. Zum einen ist dieses Dateisystem durch seinen Layer-Aufbau nicht für hohen Durchsatz optimiert, zum anderen – und das ist vermutlich entscheidender – gehen die Daten verloren, wenn der Container z. B. bei einem Releasewechsel durch einen neuen ersetzt wird.
Für persistente Daten können Container sog. Bind Mounts oder Volumes benutzen. Im Folgenden nehmen wir Volumes an, da sie im Vergleich bequemer sind und auch nicht ausschließlich mit dem Dateisystem des Docker Hosts arbeiten müssen. Die Verwendung eines Volumes im Container ähnelt der Anbindung von Devices (wie bspw. Plattenpartitionen) an das Dateisystem eines Linux-Hosts: Das Volume wird an ein Zielverzeichnis im Container, den sog. Mount Point, angebunden. Der docker
–run
-Befehl akzeptiert dazu die Option -v
: docker run ... -v VolumeName:MountPointPath ...
Alle I/O-Operationen im Mount Point des Containers landen dann schließlich im außerhalb des Containers liegenden Volume. Es gibt dabei ein paar spezielle Eigenschaften, die man bedenken muss:
- Sollte das Zielverzeichnis im Container Image nicht vorhanden sein, wird es automatisch angelegt – mit Standard-Eigentümer und -Rechten.
- Ist das Zielverzeichnis bereits vorhanden, übernimmt das externe Volume Eigentümer, Rechte und eventuellen Inhalt!
Um gewährleisten zu können, dass die Prozesse im Container auf das angebundene Volume zugreifen dürfen, muss daher das Zielverzeichnis im Container Image mit dem gewünschten Eigentümer und den notwendigen Zugriffsrechten angelegt werden. Unabdingbar ist das, wenn der Container rootless ist, also mit einem schwächer autorisierten User als root
läuft.
Guter Stil ist es darüber hinaus, Mount Points mit Hilfe von VOLUME
im Dockerfile zu deklarieren.