1. Home
  2. Linux
  3. Docker
  4. Daten mit Bind Mounts persistent speichern

Daten mit Bind Mounts persistent speichern

Lesedauer: 15 Minuten

Container besitzen eine eigene beschreibbare Dateisystemschicht, in der während des Betriebs Dateien angelegt und verändert werden können. Diese Daten bleiben beim Stoppen und erneuten Starten des Containers erhalten, gehen jedoch verloren, sobald der Container entfernt wird. Für Dateien, die unabhängig vom Lebenszyklus eines Containers bestehen bleiben sollen, bietet Docker verschiedene Möglichkeiten der persistenten Speicherung.

Eine davon sind Bind Mounts. Sie ermöglichen es, Dateien oder Verzeichnisse des Docker-Hosts direkt in das Dateisystem eines Containers einzubinden. Dadurch können Anwendungen innerhalb des Containers auf Daten zugreifen, die außerhalb seiner beschreibbaren Schicht gespeichert sind.

Im folgenden Praxisbeispiel wird ein nginx-Webserver so eingerichtet, dass er eine HTML-Datei aus einem Verzeichnis des Docker-Hosts ausliefert. Anschließend wird untersucht, wie sich Änderungen an der Datei auswirken, welche Zugriffsbeschränkungen möglich sind und was mit den Daten geschieht, wenn der Container entfernt und neu erstellt wird.

Die beschreibbare Dateisystemschicht eines Containers

Ein Docker-Image besteht aus mehreren schreibgeschützten Dateisystemschichten (Layers), die unter anderem die Anwendung, benötigte Bibliotheken und Konfigurationsdateien enthalten. Beim Erstellen eines Containers ergänzt Docker diese Schichten um eine eigene beschreibbare Schicht (Writable Layer).

Während die Image-Schichten unverändert bleiben und von mehreren Containern gemeinsam genutzt werden können, besitzt jeder Container seine eigene beschreibbare Schicht. Werden innerhalb eines Containers neue Dateien angelegt oder vorhandene Dateien verändert, speichert Docker diese Änderungen dort. Bei Änderungen an Dateien aus den Image-Schichten kommt dabei das sogenannte Copy-on-Write-Verfahren zum Einsatz.

Die beschreibbare Schicht ist an den jeweiligen Container gebunden. Beim Stoppen und erneuten Starten bleiben ihre Daten erhalten. Wird der Container hingegen mit docker rm entfernt, löscht Docker auch dessen beschreibbare Schicht. Ein anschließend aus demselben Image erstellter Container beginnt wieder mit einer neuen, zunächst unveränderten beschreibbaren Schicht.

Für Daten, die einen Containerwechsel überstehen müssen, ist diese Art der Speicherung daher ungeeignet. Docker bietet hierfür insbesondere zwei Möglichkeiten: Bind Mounts und Volumes. Bei beiden Verfahren werden Daten außerhalb der beschreibbaren Container-Schicht gespeichert und über einen Mount in das Dateisystem des Containers eingebunden.

Der wesentliche Unterschied liegt in der Verwaltung des Speicherorts. Bei einem Bind Mount wird ein konkreter Pfad des Docker-Hosts angegeben, während Docker bei einem Volume den Speicherbereich selbst verwaltet. Im Folgenden betrachten wir zunächst die Bind Mounts.

Für die folgenden Untersuchungen verwenden wir einen Docker-Host mit Debian 13 und einen nginx-Container namens academy-bind-nginx-01. Der Container basiert auf dem Image nginx:stable-alpine und stellt zunächst die nginx-Standardseite über Port 8081 des Docker-Hosts bereit.

Bevor wir eigene Dateien einbinden, untersuchen wir die vorhandene Speicherzuordnung und das Dateisystem des Containers. Damit lässt sich feststellen, welche Daten bereits im Image vorhanden sind, welche Änderungen während des Containerbetriebs entstanden sind und ob externe Speicherbereiche verwendet werden.

Bind Mounts am Beispiel eines nginx-Containers

Für die folgenden Untersuchungen verwenden wir einen Docker-Host mit Debian 13 und einen nginx-Container namens academy-bind-nginx-01. Der Container basiert auf dem Image nginx:stable-alpine und stellt zunächst die nginx-Standardseite über Port 8081 des Docker-Hosts bereit.

Bevor wir eigene Dateien einbinden, untersuchen wir die vorhandene Speicherzuordnung und das Dateisystem des Containers. Damit lässt sich feststellen, welche Daten bereits im Image vorhanden sind, welche Änderungen während des Containerbetriebs entstanden sind und ob externe Speicherbereiche verwendet werden.

Vorhandene Mounts überprüfen

Mit docker inspect lässt sich die Konfiguration eines Containers untersuchen. Über die Eigenschaft Mounts werden alle eingebundenen Docker-Volumes und Bind Mounts angezeigt.

$ sudo docker inspect --format '{{json .Mounts}}' academy-bind-nginx-01
[]

Die Option --format beschränkt die Ausgabe auf die angegebene Eigenschaft. Der Ausdruck {{json .Mounts}} gibt die Mount-Konfiguration im JSON-Format zurück. Vor der Einrichtung eines Bind Mounts liefert der Container folgende Ausgabe: []

Die leere Liste zeigt, dass der Container weder Bind Mounts noch Docker-Volumes verwendet. Seine Dateien stammen somit aus den Image-Schichten oder wurden in seiner beschreibbaren Container-Schicht angelegt beziehungsweise verändert.

Vorhandene Dateien und Änderungen untersuchen

Das Standard-Webverzeichnis des offiziellen nginx-Images befindet sich unter /usr/share/nginx/html. Mit docker exec können wir dessen Inhalt direkt im laufenden Container anzeigen:

$ sudo docker exec academy-bind-nginx-01 ls -l /usr/share/nginx/html/
-rw-r--r-- 1 root root 497 Oct  2 17:14 50x.html
-rw-r--r-- 1 root root 896 Oct  2 17:14 index.html

Die Datei index.html enthält die standardmäßig ausgelieferte Startseite. 50x.html dient als Fehlerseite für bestimmte HTTP-Serverfehler. Ob diese Dateien seit der Erstellung des Containers verändert wurden, lässt sich mit docker diff überprüfen:

$ sudo docker diff academy-bind-nginx-01
C /var
C /var/cache
C /var/cache/nginx
A /var/cache/nginx/client_temp
A /var/cache/nginx/fastcgi_temp
A /var/cache/nginx/proxy_temp
A /var/cache/nginx/scgi_temp
A /var/cache/nginx/uwsgi_temp
C /root
A /root/.ash_history
C /run
A /run/nginx.pid
C /etc
C /etc/nginx
C /etc/nginx/conf.d
C /etc/nginx/conf.d/default.conf

Docker kennzeichnet dabei Änderungen mit drei Buchstaben:

  • A (Added): Eine Datei oder ein Verzeichnis wurde hinzugefügt.
  • C (Changed): Eine Datei oder ein Verzeichnis wurde verändert.
  • D (Deleted): Eine Datei oder ein Verzeichnis wurde gelöscht.

In diesem Beispiel wurden unter anderem folgende Änderungen festgestellt:

C /var/cache/nginx
A /var/cache/nginx/client_temp
A /var/cache/nginx/fastcgi_temp
A /var/cache/nginx/proxy_temp
C /etc/nginx/conf.d/default.conf

Die temporären Verzeichnisse wurden während der Initialisierung beziehungsweise des Betriebs von nginx angelegt. Auch die Standardkonfiguration wurde gegenüber dem Image verändert. Das nginx-Image enthält Startskripte, die beispielsweise die IPv6-Konfiguration automatisch anpassen können. Das Webverzeichnis /usr/share/nginx/html erscheint dagegen nicht in der Ausgabe. Seine Dateien wurden somit gegenüber dem Image nicht verändert.

Die Untersuchung verdeutlicht, dass auch ein Container ohne externe Mounts Dateien anlegen und verändern kann. Diese Änderungen bleiben jedoch an seine beschreibbare Container-Schicht gebunden und gehen beim Entfernen des Containers verloren.

Verzeichnis auf dem Docker-Host vorbereiten

Für die persistente Speicherung der HTML-Dateien wird ein Verzeichnis auf dem Docker-Host benötigt. Dieses wird anschließend über einen Bind Mount in das Dateisystem des nginx-Containers eingebunden.

Als Speicherort dient folgender Pfad: /opt/docker/academy-bind-nginx-01/html/

Die Verzeichnisstruktur ist frei wählbar und dient der übersichtlichen Organisation der Containerdaten auf dem Host. Docker schreibt weder den Verzeichnisnamen noch dessen Speicherort vor.

$ sudo mkdir -p /opt/docker/academy-bind-nginx-01/html

Zu diesem Zeitpunkt besteht noch keine Verbindung zwischen dem Host-Verzeichnis und dem nginx-Container.

HTML-Datei erstellen

Im vorbereiteten Verzeichnis wird eine einfache HTML-Datei angelegt, die später von nginx ausgeliefert werden soll:

$ sudo vi /opt/docker/academy-bind-nginx-01/html/index.html

Die Datei erhält folgenden Inhalt:

<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <title>Docker Lernprojekt</title>
</head>
<body>
    <h1>Docker Bind Mount</h1>
    <p>Diese Webseite liegt auf dem Docker-Host.</p>
    <p>Sie wird von nginx aus einem Container ausgeliefert.</p>
</body>
</html>

Nach dem Speichern werden die Existenz und die Dateiberechtigungen überprüft:

$ ls -l /opt/docker/academy-bind-nginx-01/html/index.html
-rw-r--r-- 1 root root 284 Oct 30 15:35 /opt/docker/academy-bind-nginx-01/html/index.html

Die Datei gehört dem Benutzer root und der Gruppe root. Mit den Berechtigungen 644 darf der Eigentümer die Datei lesen und verändern, während andere Benutzer lediglich lesenden Zugriff erhalten. Damit ist die Datei grundsätzlich auch für den nginx-Prozess lesbar, sofern die Berechtigungen der übergeordneten Verzeichnisse den Zugriff zulassen.

Die HTML-Datei befindet sich nun auf dem Docker-Host und bleibt dort unabhängig vom Lebenszyklus eines Containers gespeichert. Die Einbindung in das Dateisystem des nginx-Containers erfolgt im nächsten Abschnitt.

nginx-Container mit Bind Mount erstellen

Da der Container academy-bind-nginx-01 bereits existiert, muss er zunächst entfernt und anschließend mit der gewünschten Mount-Konfiguration neu erstellt werden. Docker erlaubt es nicht, einem bestehenden Container nachträglich über docker run einen Bind Mount hinzuzufügen.

Vor dem Entfernen ist sicherzustellen, dass keine benötigten Daten ausschließlich in der beschreibbaren Container-Schicht liegen und die Startkonfiguration bekannt ist. Im vorliegenden Beispiel handelt es sich um einen unveränderten nginx-Testcontainer, dessen Einstellungen bekannt sind.

Der Container wird zunächst gestoppt und anschließend entfernt:

$ sudo docker stop academy-bind-nginx-01
$ sudo docker rm academy-bind-nginx-01

Dabei wird die beschreibbare Container-Schicht gelöscht. Das verwendete Image nginx:stable-alpine bleibt erhalten und kann unmittelbar für einen neuen Container verwendet werden. Der neue Container erhält denselben Namen und die bisherigen Startparameter, zusätzlich jedoch einen Bind Mount für das vorbereitete Host-Verzeichnis:

$ sudo docker run -d \
  --name academy-bind-nginx-01 \
  --restart unless-stopped \
  -p 8081:80 \
  --mount type=bind,source=/opt/docker/academy-bind-nginx01/html,target=/usr/share/nginx/html,readonly \
  nginx:stable-alpine

Die grundlegenden Parameter von docker run wurden bereits im Artikel zur Erstellung und Verwaltung eines Containers behandelt. Entscheidend ist hier die Option --mount, mit der die Einbindung des Host-Verzeichnisses konfiguriert wird.

Der Mount setzt sich aus folgenden Eigenschaften zusammen:

  • type=bind legt fest, dass ein Bind Mount verwendet wird.
  • source=/opt/docker/academy-bind-nginx-01/html bezeichnet das einzubindende Verzeichnis auf dem Docker-Host.
  • target=/usr/share/nginx/html bestimmt den Pfad, unter dem das Host-Verzeichnis innerhalb des Containers erscheint.
  • readonly bindet das Verzeichnis schreibgeschützt ein. Der Container kann die Dateien lesen, aber über diesen Mount nicht verändern.

Der Inhalt des Host-Verzeichnisses wird dabei nicht in den Container kopiert. Stattdessen stellt Docker das Verzeichnis an der angegebenen Stelle des Container-Dateisystems bereit.

Die nginx-Konfiguration enthält bereits die erforderlichen Direktiven:

$ sudo docker exec academy-bind-nginx-01 cat /etc/nginx/conf.d/default.conf
---snip---
location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
}
---snap---

Über root ist das Webverzeichnis festgelegt. Die Direktive index bestimmt, welche Datei bei einer Anfrage an ein Verzeichnis standardmäßig ausgeliefert wird.

Da das Host-Verzeichnis unter /usr/share/nginx/html eingebunden wurde, findet nginx dort die zuvor erstellte index.html. Eine Änderung der nginx-Konfiguration ist nicht erforderlich.

Dateien, die ursprünglich an dieser Stelle im Image vorhanden waren, werden durch den Bind Mount verdeckt, aber nicht gelöscht. Sie sind innerhalb dieses Containers am betreffenden Pfad nicht mehr sichtbar.

Nach dem Start ist die Webseite über Port 8081 des Docker-Hosts erreichbar:

Änderungen an Dateien ohne Containerneustart

Ein wesentlicher Vorteil von Bind Mounts besteht darin, dass Änderungen an eingebundenen Dateien unmittelbar im Dateisystem des Containers sichtbar werden. Ein erneutes Erstellen des Containers oder Images ist dafür nicht erforderlich.

Zum Nachweis wird die HTML-Datei auf dem Docker-Host bearbeitet:

$ sudo vi /opt/docker/academy-bind-nginx-01/html/index.html

Innerhalb des <body>-Elements wird ein zusätzlicher Absatz eingefügt:
<p>Diese Zeile wurde nach dem Containerstart hinzugefügt</p>

<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <title>Docker Lernprojekt</title>
</head>
<body>
    <h1>Docker Bind Mount</h1>
    <p>Diese Webseite liegt auf dem Docker-Host.</p>
    <p>Sie wird von nginx aus einem Container ausgeliefert.</p>
    <p>Diese Zeile wurde nach dem Containerstart hinzugefügt.</p>
</body>
</html>

Der Browser zeigt nun auch den ergänzten Absatz, an obwohl der Container während der Änderung durchgehend aktiv geblieben ist.

Das Verhalten ergibt sich aus der Funktionsweise des Bind Mounts: Docker erstellt keine separate Kopie der eingebundenen Dateien, sondern stellt das Host-Verzeichnis unter dem angegebenen Zielpfad im Container bereit. Änderungen am Dateiinhalt werden daher auch über diesen Pfad sichtbar.

nginx liest die angeforderte HTML-Datei und überträgt ihren Inhalt an den Client. Die Interpretation und Darstellung des HTML-Codes erfolgen anschließend durch den Browser.

Damit lassen sich statische Webinhalte unabhängig vom Container-Image aktualisieren. Änderungen an der Anwendungskonfiguration oder an ausführbarem Programmcode können dagegen, abhängig von der jeweiligen Anwendung, zusätzliche Maßnahmen wie einen Reload, Neustart oder eine erneute Bereitstellung erfordern.

Bei der Auslieferung können Caching-Mechanismen des Webservers, des Betriebssystems oder des Browsers eine Rolle spielen. In der verwendeten nginx-Standardkonfiguration werden Änderungen an der statischen HTML-Datei bei einer erneuten HTTP-Anfrage jedoch ohne Neustart des Webservers berücksichtigt.

Schreibschutz des Bind Mounts überprüfen

Beim Erstellen des Containers wurde der Bind Mount mit der Option readonly eingerichtet. Dadurch kann nginx die eingebundenen HTML-Dateien lesen, jedoch nicht verändern.

Ob diese Einschränkung tatsächlich greift, lässt sich durch den Versuch überprüfen, innerhalb des Containers eine neue Datei im eingebundenen Verzeichnis anzulegen:

$ sudo docker exec academy-bind-nginx-01 touch /usr/share/nginx/html/test.txt
touch: /usr/share/nginx/html/test.txt: Read-only file system

Der Befehl wird innerhalb des laufenden Containers ausgeführt. Da das Verzeichnis schreibgeschützt eingebunden ist, schlägt der Versuch fehl. Bemerkenswert ist, dass docker exec den Befehl hier als Benutzer root ausführt. Trotzdem wird der Schreibzugriff verweigert.

Diese Einschränkung betrifft allerdings nur den eingebundenen Speicherbereich. Die übrige beschreibbare Dateisystemschicht des Containers bleibt davon unberührt. Ein schreibgeschützter Bind Mount ersetzt daher weder eine geeignete Rechteverwaltung noch die Absicherung des Containers.

Der Schreibschutz eines Read-only-Mounts unterscheidet sich von den gewöhnlichen Linux-Dateiberechtigungen. Während klassische Berechtigungen wie 644 vom Eigentümer und den Zugriffsrechten eines Prozesses abhängen, wird die Schreibbeschränkung des Mounts auf Dateisystemebene durchgesetzt. Auch ein Root-Prozess innerhalb des Containers kann über diesen Mount keine Dateien verändern.

Mount-Konfiguration mit docker inspect untersuchen

Die tatsächlich verwendete Mount-Konfiguration kann über docker inspect angezeigt werden:

$ sudo docker inspect --format '{{json .Mounts}}' academy-bind-nginx-01
[{"Type":"bind","Source":"/opt/docker/academy-bind-nginx-01/html","Destination":"/usr/share/nginx/html","Mode":"","RW":false,"Propagation":"rprivate"}]

Die einzelnen Eigenschaften haben folgende Bedeutung:

  • Type: Art des Mounts, in diesem Fall bind.
  • Source: Quellverzeichnis auf dem Docker-Host.
  • Destination: Zielverzeichnis innerhalb des Containers.
  • Mode: Zusätzliche Modusangaben; hier ist das Feld leer.
  • RW: Gibt an, ob der Mount beschreibbar ist. Der Wert false bestätigt die schreibgeschützte Einbindung.
  • Propagation: Regelt die Weitergabe von Mount-Ereignissen. rprivate verhindert die gegenseitige Weitergabe solcher Ereignisse zwischen dem Mount und seiner Umgebung.

Die Kombination aus RW: false und dem fehlgeschlagenen Schreibversuch bestätigt, dass der Bind Mount wie vorgesehen schreibgeschützt eingerichtet wurde.

Für statische Webseiten ist diese Konfiguration sinnvoll, da der Webserver lediglich lesenden Zugriff auf die bereitgestellten Inhalte benötigt. Änderungen an den HTML-Dateien erfolgen weiterhin direkt auf dem Docker-Host.

Persistenz beim Entfernen und Neuerstellen des Containers

Der bisherige Versuch hat gezeigt, dass nginx über einen Bind Mount auf Dateien des Docker-Hosts zugreifen kann. Abschließend wird überprüft, ob diese Dateien auch dann erhalten bleiben, wenn der Container vollständig entfernt und anschließend neu erstellt wird.

Dazu wird der laufende Container gestoppt und entfernt:

$ sudo docker stop academy-bind-nginx-01
$ sudo docker rm academy-bind-nginx-01

Mit docker rm werden der Container und seine beschreibbare Dateisystemschicht gelöscht. Das zugrunde liegende Image sowie die über den Bind Mount bereitgestellten Dateien auf dem Host bleiben dagegen erhalten.

Anschließend wird ein neuer Container mit derselben Mount-Konfiguration erstellt:

$ sudo docker run -d \
  --name academy-bind-nginx-01 \
  --restart unless-stopped \
  -p 8081:80 \
  --mount type=bind,source=/opt/docker/academy-bind-nginx-01/html,target=/usr/share/nginx/html,readonly \
  nginx:stable-alpine

Obwohl der neue Container denselben Namen trägt, handelt es sich um eine eigenständige Instanz mit einer neuen Container-ID und einer neuen beschreibbaren Dateisystemschicht.

Der Bind Mount stellt jedoch wieder dieselben Dateien des Docker-Hosts unter /usr/share/nginx/html bereit.

Damit ist nachgewiesen, dass die über einen Bind Mount bereitgestellten Daten unabhängig vom Lebenszyklus des Containers erhalten bleiben. Ausschlaggebend ist dabei nicht der Containername, sondern die korrekte Zuordnung zwischen dem Quellverzeichnis auf dem Host und dem Zielverzeichnis innerhalb des Containers. Auch ein Container mit einem anderen Namen könnte dieselben Dateien verwenden, sofern er mit einer entsprechenden Mount-Konfiguration erstellt wird.

Die Persistenz der Dateien bedeutet allerdings nicht, dass auch die übrige Containerkonfiguration erhalten bleibt. Portzuordnungen, Umgebungsvariablen, Netzwerkeinstellungen und andere Startparameter müssen beim Neuerstellen erneut angegeben oder über eine deklarative Konfiguration, beispielsweise mit Docker Compose, bereitgestellt werden.

Fazit

Bind Mounts ermöglichen es, Dateien und Verzeichnisse des Docker-Hosts direkt in das Dateisystem eines Containers einzubinden. Die Daten befinden sich dabei außerhalb der beschreibbaren Container-Schicht und bleiben auch dann erhalten, wenn der Container gestoppt, entfernt oder durch eine neue Instanz ersetzt wird.

Das nginx-Beispiel verdeutlicht, dass eingebundene Dateien ohne Änderungen am Container-Image bereitgestellt und aktualisiert werden können. Gleichzeitig lässt sich der Zugriff durch eine schreibgeschützte Einbindung einschränken. Für Anwendungen, die lediglich lesenden Zugriff auf Konfigurationsdateien oder statische Inhalte benötigen, ist dies eine sinnvolle Sicherheitsmaßnahme.

Bind Mounts bieten eine direkte Kontrolle über den Speicherort der Daten und eignen sich insbesondere dann, wenn Dateien gezielt auf dem Host verwaltet oder bearbeitet werden sollen. Allerdings entsteht dadurch auch eine Abhängigkeit von der Verzeichnisstruktur und den Zugriffsrechten des Hostsystems. Fehlerhafte Mount-Konfigurationen oder zu weitreichende Schreibberechtigungen können sich unmittelbar auf die Sicherheit und Integrität der Host-Dateien auswirken.

Eine Alternative stellen Docker-Volumes dar. Diese werden von Docker selbst verwaltet und bieten insbesondere für die dauerhafte Speicherung von Anwendungsdaten weitere Möglichkeiten. Ihre Einrichtung, Verwaltung und Unterschiede zu Bind Mounts werden in einem separaten Artikel behandelt.

Befehlszeilenreferenz

  • docker diff <container> : Zeigt Änderungen am beschreibbaren Dateisystem eines Containers gegenüber dem Image (A = hinzugefügt, C = verändert, D = gelöscht).
  • docker inspect --format '{{json .Mounts}}' <container> : Zeigt die eingebundenen Volumes und Bind Mounts einschließlich Quellpfad, Zielpfad und Zugriffsmodus.
  • docker run --mount type=bind,source=<host-pfad>,target=<container-pfad>,readonly : Bindet ein Host-Verzeichnis schreibgeschützt in einen neuen Container ein. Weitere Startparameter und das Image müssen ergänzt werden.
  • -v <host-pfad>:<container-pfad>:ro : Kurzschreibweise für einen schreibgeschützten Bind Mount als Option von docker run.
  • docker exec <container> touch <dateipfad> : Versucht, eine Datei innerhalb des Containers anzulegen. Eignet sich zur Überprüfung eines schreibgeschützten Mounts.

Loading

Updated on 30. Oktober 2026
Was this article helpful?

Related Articles