Docker/Buch/03 Grundlagen/05 Volumes: Unterschied zwischen den Versionen

Aus Foxwiki
Wechseln zu:Navigation, Suche
Keine Bearbeitungszusammenfassung
 
(5 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
'''Docker/Buch/03 Grundlagen/05 Volumes''' - Datenspeicherung in Volumes
'''Docker/Buch/03 Grundlagen/05 Volumes''' - Datenspeicherung in Volumes


= Beschreibung =
== Beschreibung ==
Wie und wo werden Container Daten gespeichert?
Wie und wo werden Container Daten gespeichert?
* Was würde sich besser zur Beantwortung dieser Fragen eignen als ein Container mit einem Datenbankserver? Wir haben uns hier für das mit MySQL kompatible Datenbanksystem MariaDB entschieden.
* Was würde sich besser zur Beantwortung dieser Fragen eignen als ein Container mit einem Datenbankserver?
* Sie werden sehen, Sie müssen kein Datenbankexperte sein, um dem Beispiel folgen zu können. (Mehr Tipps zum praktischen Einsatz von MySQL und MariaDB folgen in Abschnitt 10.1.)
* Wir haben uns hier für das mit MySQL kompatible Datenbanksystem MariaDB entschieden
Im Docker Hub gibt es für die Datenbankserver MySQL und MariaDB diverse Images.
Für diesen Abschnitt haben wir mit dem offiziellen MariaDB-Image gearbeitet.


Es ist auf der folgenden Seite dokumentiert:
Sie werden sehen, Sie müssen kein Datenbankexperte sein, um dem Beispiel folgen zu können
*https://hub.docker.com/r/_/mariadb


Beim Einrichten des Containers mit dem folgenden Kommando wird das root- Passwort für den Datenbankserver als Parameter übergeben.
; Siehe auch
* Das ist kein optimaler Mechanismus, weil das Passwort kurz im Klartext in der Prozessliste für alle sichtbar ist.
* Praktischen Einsatz von [[MySQL und MariaDB]]
* Eine bessere Vorgehensweise präsentieren wir Ihnen in Abschnitt 5.4, »Passwörter und andere Geheimnisse«.
* Der Inhalt von MYSQL_ROOT_PASSWORD kann später auch mit docker inspect mariadb-test ausgelesen werden – allerdings nur von Anwendern, die selbst docker ausführen dürfen.
Anstelle von MYSQL_ROOT_PASSWORD können Sie die gleichwertige Variable MARIADB_
ROOT_PASSWORD verwenden.
* Wir bleiben in diesem Kapitel bei MYSQL_xxx , weil diese Variablennamen universell für MariaDB- und für MySQL-Images funktionieren.


Im Docker Hub gibt es für die Datenbankserver MySQL und MariaDB diverse Images
Für diesen Abschnitt haben wir mit dem offiziellen MariaDB-Image gearbeitet
Es ist auf der folgenden Seite dokumentiert
* https://hub.docker.com/r/_/mariadb
Beim Einrichten des Containers mit dem folgenden Kommando wird das root- Passwort für den Datenbankserver als Parameter übergeben
* Das ist kein optimaler Mechanismus, weil das Passwort kurz im Klartext in der Prozessliste für alle sichtbar ist
* Eine bessere Vorgehensweise präsentieren wir Ihnen in Abschnitt 5.4, »Passwörter und andere Geheimnisse«
* Der Inhalt von MYSQL_ROOT_PASSWORD kann später auch mit docker inspect mariadb-test ausgelesen werden – allerdings nur von Anwendern, die selbst docker ausführen dürfen
Anstelle von MYSQL_ROOT_PASSWORD können Sie die gleichwertige Variable MARIADB_ROOT_PASSWORD verwenden
Wir bleiben her bei MYSQL_xxx , weil diese Variablennamen universell für MariaDB- und für MySQL-Images funktionieren
<syntaxhighlight lang="bash" highlight="" line copy>
  docker run -d --name mariadb - test \
  docker run -d --name mariadb - test \
  -e MYSQL_RO O T _P A S S W OR D = geheim mariadb
-e MYSQL_RO O T _P A S S W OR D = geheim mariadb
</syntaxhighlight>


Wenn Sie Podman verwenden, müssen Sie für MariaDB docker.io als Image-Registry auswählen.
Wenn Sie Podman verwenden, müssen Sie für MariaDB docker.io als Image-Registry auswählen
* Die interaktive Auswahl vermeiden Sie, indem Sie gleich den vollständigen Image-Namen angeben.
* Die interaktive Auswahl vermeiden Sie, indem Sie gleich den vollständigen Image-Namen angeben
* Dieser funktioniert natürlich auch in Kombination mit docker.


Dieser funktioniert natürlich auch in Kombination mit docker
<syntaxhighlight lang="bash" highlight="1" line copy>
  podman run -d --name mariadb - test \
  podman run -d --name mariadb - test \
  -e MYSQL_ROO T _ P AS S W O R D = geheim docker .  
-e MYSQL_ROO T _ P AS S W O R D = geheim docker.io /library / mariadb
* io /library / mariadb
</syntaxhighlight>


Das Kommando docker run gibt zwar die ID des neuen Containers aus, zeigt aber ansonsten keine Statusinformationen an, die auf einen erfolgreichen Start hinweisen.
Das Kommando docker run gibt zwar die ID des neuen Containers aus, zeigt aber ansonsten keine Statusinformationen an, die auf einen erfolgreichen Start hinweisen
Sie können sich mit docker ps davon überzeugen, dass der Container wirklich läuft:


Sie können sich mit docker ps davon überzeugen, dass der Container wirklich läuft
<syntaxhighlight lang="bash" highlight="1" line copy>
  docker ps
  docker ps
  CONTAINE R ID ...             COMMAND   CREATED             NAMES
  CONTAINE R ID ... COMMAND CREATED NAMES
  02 f5b1017a b b               mysqld   52 seconds ago     mariadb -test
  02 f5b1017a b b mysqld 52 seconds ago mariadb -test
  ...
  ..
</syntaxhighlight>


Sollte docker ps keine Ausgaben liefern bzw. sollte mariadb-test in der Liste der aktiven Container fehlen, ergründen Sie am besten mit docker logs die Fehlerursache.
Sollte docker ps keine Ausgaben liefern bzw. sollte mariadb-test in der Liste der aktiven Container fehlen, ergründen Sie am besten mit docker logs die Fehlerursache
Wenn Sie beispielsweise vergessen haben, das gewünschte Passwort mit der Option
Wenn Sie beispielsweise vergessen haben, das gewünschte Passwort mit der Option
-e zu übergeben, erhalten Sie mit docker logs die folgende Fehlermeldung:
-e zu übergeben, erhalten Sie mit docker logs die folgende Fehlermeldung


<syntaxhighlight lang="bash" highlight="" line copy>
  docker logs mariadb - test
  docker logs mariadb - test
  Entrypoi n t script for MariaDB Server 1:11.0.2 + maria ~ ubu2204
  Entrypoi n t script for MariaDB Server 1:11.0.2 + maria ~ ubu2204
Zeile 47: Zeile 59:
  Database is uninitia l i ze d and password option is not specifie d
  Database is uninitia l i ze d and password option is not specifie d
  You need to specify one of MARIADB_ROOT_P AS SW OR D ,
  You need to specify one of MARIADB_ROOT_P AS SW OR D ,
  MARIADB_ R O O T_ P A S SW O R D _ HA S H ...
  MARIADB_ R O O T_ P A S SW O R D _ HA S H ..
</syntaxhighlight>


Beachten Sie, dass Sie vor einem neuerlichen Start den zuletzt erzeugten Container löschen, also docker rm mariadb-test ausführen müssen.
Beachten Sie, dass Sie vor einem neuerlichen Start den zuletzt erzeugten Container löschen, also docker rm mariadb-test ausführen müssen


Mehrzeilige Kommandos
; Mehrzeilige Kommandos
Wenn wir in diesem Buch Kommandos aus Platzgründen über zwei Zeilen verteilen müssen, kennzeichnen wir das Ende der umgebrochenen Zeile mit dem Zeichen \
* Unter Linux und macOS haben Sie nun die Wahl, ob Sie das Kommando einfach in einer Zeile eingeben oder ob Sie das Kommando wie im Buch abgedruckt mehrzeilig samt aller \-Zeichen eingeben
Beachten Sie aber, dass mehrzeilige Kommandos in der PowerShell unter Windows mit dem Zeichen ` zu trennen sind!


Wenn wir in diesem Buch Kommandos aus Platzgründen über zwei Zeilen verteilen müssen, kennzeichnen wir das Ende der umbrochenen Zeile mit dem Zeichen \.
; PowerShell
* Unter Linux und macOS haben Sie nun die Wahl, ob Sie das Kommando einfach in einer Zeile eingeben oder ob Sie das Kommando wie im Buch abgedruckt mehrzeilig samt aller
In der PowerShell müssten Sie das obige Kommando daher entweder in einer langen Zeile oder wie folgt eingeben
\-Zeichen eingeben.
Beachten Sie aber, dass mehrzeilige Kommandos in der PowerShell unter Windows mit dem Zeichen ` zu trennen sind! In der PowerShell müssten Sie das obige Kommando daher entweder in einer langen Zeile oder wie folgt eingeben:
docker run -d --name mariadb-test `
-e MYSQL_ROOT_PASSWORD=geheim mariadb


Wenn der Start erfolgreich war, läuft der Datenbankserver wegen der Option -d im Hintergrund weiter, bis der Container explizit wieder gestoppt wird:
<syntaxhighlight lang="bash" highlight="" line copy>
docker run -d --name mariadb-test -e MYSQL_ROOT_PASSWORD=geheim mariadb
</syntaxhighlight>


Wenn der Start erfolgreich war, läuft der Datenbankserver wegen der Option -d im Hintergrund weiter, bis der Container explizit wieder gestoppt wird
<syntaxhighlight lang="bash" highlight="" line copy>
  docker stop mariadb - test
  docker stop mariadb - test
</syntaxhighlight>


Speicherung der Datenbank in einem automatisch erzeugten Volume MariaDB speichert grundsätzlich alle Datenbankdateien im Verzeichnis /var/lib/
Speicherung der Datenbank in einem automatisch erzeugten Volume MariaDB speichert grundsätzlich alle Datenbankdateien im Verzeichnis /var/lib/
mysql.
mysql
* Im Dockerfile von MariaDB, also in der Beschreibung des Images, ist /var/
* Im Dockerfile von MariaDB, also in der Beschreibung des Images, ist /var/
lib/mysql aber als Volume gekennzeichnet.
lib/mysql aber als Volume gekennzeichnet
* Das bedeutet, dass dieses Verzeichnis außerhalb des Containers angelegt wird.
* Das bedeutet, dass dieses Verzeichnis außerhalb des Containers angelegt wird


Unter Linux richtet Docker dazu ein Unterverzeichnis innerhalb von /var/
Unter Linux richtet Docker dazu ein Unterverzeichnis innerhalb von
lib/docker/volumes auf dem Host-Rechner ein.
* Wenn Sie mit Rootless Docker arbeiten, landet das Unterverzeichnis entsprechend in .local/share/docker/
volumes.
* Podman verwendet das Verzeichnis .local/share/containers/storage/
volumes.
* Den genauen Verzeichnisnamen können Sie mit docker inspect mariadb-test ermitteln, wenn Sie in der mehrseitigen Ausgabe dieses Kommandos nach Mounts suchen.
Unter Windows und macOS ist die Funktionsweise ganz ähnlich, allerdings wird das Volume-Verzeichnis nicht direkt im Dateisystem von Windows bzw. macOS eingerichtet, sondern innerhalb der virtuellen Maschine des Linux-Kernels, der für die Ausführung der Docker Engine zuständig ist.
* Das verstärkt den »Blackbox- Charakter« derartiger Volumes.


Was haben Sie davon, dass Docker zwischen Daten differenziert, die im Container gespeichert werden, und solchen, die außerhalb (also in einem Volume) landen? Vorerst nicht viel.
<syntaxhighlight lang="bash" highlight="" line copy>
/var/lib/docker/volumes
</syntaxhighlight>
auf dem Host-Rechner ein
 
Wenn Sie mit Rootless Docker arbeiten, landet das Unterverzeichnis entsprechend in .local/share/docker/
volumes
* Podman verwendet das Verzeichnis .local/share/containers/storage/ volumes
* Den genauen Verzeichnisnamen können Sie mit docker inspect mariadb-test ermitteln, wenn Sie in der mehrseitigen Ausgabe dieses Kommandos nach Mounts suchen
Unter Windows und macOS ist die Funktionsweise ganz ähnlich, allerdings wird das Volume-Verzeichnis nicht direkt im Dateisystem von Windows bzw. macOS
eingerichtet, sondern innerhalb der virtuellen Maschine des Linux-Kernels, der für die Ausführung der Docker Engine zuständig ist
* Das verstärkt den »Blackbox- Charakter« derartiger Volumes
 
Was haben Sie davon, dass Docker zwischen Daten differenziert, die im Container gespeichert werden, und solchen, die außerhalb (also in einem Volume) landen? Vorerst nicht viel
* Sowohl die Container als auch die Volumes landen in einem von
* Sowohl die Container als auch die Volumes landen in einem von


Docker verwalteten Verzeichnis (z.&nbsp;B.&nbsp;/var/lib/docker), auf dessen Inhalt Sie in keinem Fall direkt zugreifen sollten.
Docker verwalteten Verzeichnis (z.&nbsp;B.&nbsp;/var/lib/docker), auf dessen Inhalt Sie in keinem Fall direkt zugreifen sollten
Aber mit Volumes haben Sie die Möglichkeit, die Daten eines beendeten Containers später in einen neuen Container zu übernehmen.
Aber mit Volumes haben Sie die Möglichkeit, die Daten eines beendeten Containers später in einen neuen Container zu übernehmen
* Das ist z.&nbsp;B.&nbsp;dann sinnvoll, wenn Sie nach einem MariaDB-Update den vorhandenen Container löschen und durch einen neuen Container mit der aktuellen MariaDB-Version ersetzen möchten.
* Das ist z.&nbsp;B.&nbsp;dann sinnvoll, wenn Sie nach einem MariaDB-Update den vorhandenen Container löschen und durch einen neuen Container mit der aktuellen MariaDB-Version ersetzen möchten
* Bei einem derartigen Update wollen Sie natürlich Ihre Daten nicht verlieren.
* Bei einem derartigen Update wollen Sie natürlich Ihre Daten nicht verlieren


Außerdem werden Sie im nächsten Abschnitt lernen, wie Sie Volumes mit eigenen, lokalen Verzeichnissen verbinden und so gewissermaßen aus der Docker-Blackbox herauslösen können.
Außerdem werden Sie im nächsten Abschnitt lernen, wie Sie Volumes mit eigenen, lokalen Verzeichnissen verbinden und so gewissermaßen aus der Docker-Blackbox herauslösen können


Volumes analysieren
== Volumes analysieren ==
 
Das Kommando docker inspect liefert in einem mehr als 100 Zeilen langen Listing unzählige Details zu einem bestimmten Container
Das Kommando docker inspect liefert in einem mehr als 100 Zeilen langen Listing unzählige Details zu einem bestimmten Container.
* Uns interessieren an dieser Stelle vor allem die Volume-Daten:


Uns interessieren an dieser Stelle vor allem die Volume-Daten
<syntaxhighlight lang="bash" highlight="" line copy>
  docker inspect mariadb - test
  docker inspect mariadb - test
</syntaxhighlight>


  ...
<syntaxhighlight lang="bash" highlight="" line copy>
  ..
  " Mounts ": [
  " Mounts ": [
  {
{
  " Type ": "volume " ,
  " Type ": "volume " ,
  " Name ": "d19f5b86 ..." ,
  " Name ": "d19f5b86 ..." ,
  " Source ": "/ home / kofler /.
  " Source ": "/ home / kofler /local / share / docker / volumes /\
* local / share / docker / volumes /\
d19f5b86 .../ _data " ,
  d19f5b86 .../ _data " ,
  " Destinati o n ": "/ var /lib / mysql " ,
  " Destinati o n ": "/ var /lib / mysql " ,
  " Driver ": " local " ,
  " Driver ": " local " ,
Zeile 110: Zeile 134:
  " RW ": true ,
  " RW ": true ,
  " Propagati o n ": ""
  " Propagati o n ": ""
  }
}
  ],
  ],
  ...
  ..
</syntaxhighlight>


Der Container mariadb-test ist also einem Volume mit der ID d19f5b86...  
Der Container mariadb-test ist also einem Volume mit der ID d19f5b86..
* zugeordnet.
* zugeordnet
Dieses Volume befindet sich physikalisch im folgenden Verzeichnis:
Dieses Volume befindet sich physikalisch im folgenden Verzeichnis


  / home / kofler /.
<syntaxhighlight lang="bash" highlight="" line copy>
* local / share / docker / volumes / d19f5b86 .../ _data
  / home / kofler / local / share / docker / volumes / d19f5b86 .../ _data
</syntaxhighlight>


Anstatt die Volume-Daten mühsam aus dem Listing zu extrahieren, können Sie an docker inspect eine Formatoption übergeben und nur die für Sie relevanten Daten –
Anstatt die Volume-Daten mühsam aus dem Listing zu extrahieren, können Sie an docker inspect eine Formatoption übergeben und nur die für Sie relevanten Daten –
in diesem Fall alle Mounts – herausfiltern:
in diesem Fall alle Mounts – herausfiltern


  docker inspect -f '{{ .
<syntaxhighlight lang="bash" highlight="" line copy>
* Mounts }} ' mariadb - test
  docker inspect -f '{{  
Mounts }} ' mariadb - test


  [{ volume d19f5b86 ...
  [{ volume d19f5b86 ..
  / home / kofler /.
  / home / kofler / local / share / docker /volumes / d19f5b86 .../ _data
* local / share / docker /volumes / d19f5b86 .../ _data
  / var / lib / mysql
  / var / lib / mysql
  local
  local
  true }]
  true }]
</syntaxhighlight>
Sobald Sie den Namen eines Volumes kennen (hier d19f5b86...), können Sie mit docker volume inspect weitere Informationen herausfinden. (Beachten Sie, dass Sie dabei den gesamten, 64 Zeichen langen hexadezimalen Code angeben müssen


Sobald Sie den Namen eines Volumes kennen (hier d19f5b86...), können Sie mit docker volume inspect weitere Informationen herausfinden. (Beachten Sie, dass Sie dabei den gesamten, 64 Zeichen langen hexadezimalen Code angeben müssen.
Wir geben in den Listings dieses Abschnitts zur besseren Übersichtlichkeit jeweils nur die ersten 8 Stellen an.)
* Wir geben in den Listings dieses Abschnitts zur besseren Übersichtlichkeit jeweils nur die ersten 8 Stellen an.)


  docker volume inspect d19f5b86 ...
<syntaxhighlight lang="bash" highlight="" line copy>
  docker volume inspect d19f5b86 ..
  [
  [
  {
  {
Zeile 143: Zeile 172:
  " Driver ": " local " ,
  " Driver ": " local " ,
  " Labels ": null ,
  " Labels ": null ,
  " Mountpoin t ": "/ home /kofler /.
  " Mountpoin t ": "/ home /kofler / local / share / docker /\
* local / share / docker /\
volumes / d19f5b86 .../ _data " ,
  volumes / d19f5b86 .../ _data " ,
  " Name ": "d19f5b86 .." ,
  " Name ": "d19f5b86 .." ,
  " Options ": null ,
  " Options ": null ,
Zeile 151: Zeile 179:
  }
  }
  ]
  ]
</syntaxhighlight>


Leider verrät docker volume inspect nicht, wie groß ein Volume ist.
Leider verrät docker volume inspect nicht, wie groß ein Volume ist
* Diese Information liefert docker system df, allerdings nicht spezifisch für ein Volume, sondern global für alle durch Docker verwalteten Images, Container, Volumes etc.
* Diese Information liefert docker system df, allerdings nicht spezifisch für ein Volume, sondern global für alle durch Docker verwalteten Images, Container, Volumes etc
* Dementsprechend ist die Ausgabe von docker system df zumeist recht lang.
* Dementsprechend ist die Ausgabe von docker system df zumeist recht lang
* Wir haben aus dem folgenden Listing alle Informationen entfernt, die nichts mit unserem Volume zu tun haben.


Wir haben aus dem folgenden Listing alle Informationen entfernt, die nichts mit unserem Volume zu tun haben
<syntaxhighlight lang="bash" highlight="" line copy>
  docker system df -v
  docker system df -v
</syntaxhighlight>


  Images space usage : ...
<syntaxhighlight lang="bash" highlight="" line copy>
  Containe r s space usage : ...
  Images space usage : ..
  Build cache usage : ...
  Containe r s space usage : ..
  Local Volumes space usage :
  Build cache usage : ..
  VOLUME NAME       LINKS             SIZE
  Local Volumes space usage  
  d19f5b86 ...       1                 186.2 MB
  VOLUME NAME LINKS SIZE
  d19f5b86 ... 1 186.2 MB
</syntaxhighlight>


Vielleicht fragen Sie sich, warum das Volume derart groß ist: Wir haben ja noch gar keine Datenbanken erzeugt und mit Daten befüllt.
Vielleicht fragen Sie sich, warum das Volume derart groß ist: Wir haben ja noch gar keine Datenbanken erzeugt und mit Daten befüllt
* Die Volume-Größe hat mit einer
* Die Volume-Größe hat mit einer


Eigenheit des MariaDB-Servers zu tun: Beim ersten Start werden Dateien eingerichtet, in denen später Datenbanken, Transaktionen usw.
Eigenheit des MariaDB-Servers zu tun: Beim ersten Start werden Dateien eingerichtet, in denen später Datenbanken, Transaktionen usw
* gespeichert werden.
* gespeichert werden
* Die minimale Größe dieser Dateien ist bereits ziemlich beträchtlich.
* Die minimale Größe dieser Dateien ist bereits ziemlich beträchtlich
 
MariaDB-Client aufrufen


Bevor wir Ihnen im nächsten Abschnitt mehr Details zum effizienten Umgang mit Volumes verraten, möchten wir Ihnen kurz zeigen, wie Sie den MariaDB-Container ansehen bzw. analysieren können.
== MariaDB-Client aufrufen ==
* Das ist insofern nicht ganz trivial, als eine interaktive Nutzung des Containers nicht vorgesehen ist.
Bevor wir Ihnen im nächsten Abschnitt mehr Details zum effizienten Umgang mit Volumes verraten, möchten wir Ihnen kurz zeigen, wie Sie den MariaDB-Container ansehen bzw. analysieren können
* Sie können aber mit docker exec innerhalb des im Hintergrund laufenden Containers das interaktive Kommando mariadb starten. (mariadb ist ein Kommando, mit dem Sie SQL-Anweisungen auf einem MariaDB-Server ausführen können.
* Das ist insofern nicht ganz trivial, als eine interaktive Nutzung des Containers nicht vorgesehen ist
* Sie können aber mit docker exec innerhalb des im Hintergrund laufenden Containers das interaktive Kommando mariadb starten. (mariadb ist ein Kommando, mit dem Sie SQL-Anweisungen auf einem MariaDB-Server ausführen können
* Falls Sie einen Container mit einem MySQL- Server ausführen, lautet der Kommandoname entsprechend mysql.)
* Falls Sie einen Container mit einem MySQL- Server ausführen, lautet der Kommandoname entsprechend mysql.)
Als Login-Passwort geben Sie das gleiche Passwort wie beim Erzeugen des Containers an.
Als Login-Passwort geben Sie das gleiche Passwort wie beim Erzeugen des Containers an
* Wenn Sie die vorherigen Kommandos exakt nachvollzogen haben, lautet es geheim.


Wenn Sie die vorherigen Kommandos exakt nachvollzogen haben, lautet es geheim
<syntaxhighlight lang="bash" highlight="" line copy>
  docker exec -it mariadb - test mariadb -u root -p
  docker exec -it mariadb - test mariadb -u root -p
  Enter password : ******** ( root - Passwort fü r MariaDB )
  Enter password : ******** ( root - Passwort fü r MariaDB )
  Welcome to the MariaDB monitor .
  Welcome to the MariaDB monitor  
  Server version : 11.0.2 -MariaDB
  Server version : 11.0.2 -MariaDB
 
  MariaDB [( none ) ] > show status ;
  MariaDB [( none ) ] > show status ;
  ...
  ..
   
   
  MariaDB [( none ) ] > exit
  MariaDB [( none ) ] > exit
</syntaxhighlight>


Ein Blick in den Container
; Ein Blick in den Container


Wenn Sie neugierig sind und weitere Details über den Container ermitteln möchten, starten Sie parallel zum MariaDB-Server mit docker exec einen bash-Prozess für den Container:
Wenn Sie neugierig sind und weitere Details über den Container ermitteln möchten, starten Sie parallel zum MariaDB-Server mit docker exec einen bash-Prozess für den Container


docker exec -it mariadb - test / bin / bash


<syntaxhighlight lang="bash" highlight="" line copy>
docker exec -it mariadb - test / bin / bash
  root@34d e 8 6 6b f f 1 2 :/# cat / etc / os - release
  root@34d e 8 6 6b f f 1 2 :/# cat / etc / os - release
  PRETTY_N A ME =" Ubuntu 24.04.2 LTS "
  PRETTY_N A ME =" Ubuntu 24.04.2 LTS "
  ...
  ..
 
  root@34d e 8 6 6b f f 1 2 :/#         ps -ax
  root@34d e 8 6 6b f f 1 2 :/# ps -ax
  PID TTY             STAT           TIME COMMAND
  PID TTY STAT TIME COMMAND
  1 ?               Ssl             0:00 mysqld
  1 ? Ssl 0:00 mysqld
  147 ?               Ss             0:00 / bin / bash
  147 ? Ss 0:00 / bin / bash
  218 ?               R+             0:00 ps -ax
  218 ? R+ 0:00 ps -ax
 
   
   
  root@34d e 8 6 6b f f 1 2 :/# mariadbd --version
  root@34d e 8 6 6b f f 1 2 :/# mariadbd --version
  mariadbd Ver 11.0.2 -MariaDB -1:11.0. 2 + maria ~ ubu2204 for
  mariadbd Ver 11.0.2 -MariaDB -1:11.0. 2 + maria ~ ubu2204 for
  debian - linux - gnu on x86_64 ( mariadb .
  debian - linux - gnu on x86_64 ( mariadb  
* org binary distribu t io n )
org binary distribu t io n )
root@34d e 8 6 6b f f 1 2 :/# exit
</syntaxhighlight>


root@34d e 8 6 6b f f 1 2 :/#  exit
Anhand von cat /etc/os-release wissen Sie nun, dass MariaDB Ubuntu als Basis- Image verwendet


Anhand von cat /etc/os-release wissen Sie nun, dass MariaDB Ubuntu als Basis- Image verwendet.
== Logging ==
Da der MariaDB-Container im Hintergrund läuft, sehen Sie im Terminal weder Fehlermeldungen noch Logging-Ausgaben


Logging
Diese können Sie mit docker logs lesen
 
Da der MariaDB-Container im Hintergrund läuft, sehen Sie im Terminal weder Fehlermeldungen noch Logging-Ausgaben.
* Diese können Sie mit docker logs lesen:


<syntaxhighlight lang="bash" highlight="" line copy>
  docker logs mariadb - test
  docker logs mariadb - test
 
  Starting MariaDB 11.0.2 -MariaDB -1 as process 1
  Starting MariaDB 11.0.2 -MariaDB -1 as process 1
  InnoDB : Compress ed tables use zlib 1.2.11
  InnoDB : Compress ed tables use zlib 1.2.11
  InnoDB : Number of transact i o n pools : 1
  InnoDB : Number of transact i o n pools : 1
  InnoDB : Using crc32 + pclmulqdq instruct io n s
  InnoDB : Using crc32 + pclmulqdq instruct io n s
  ...
  ..
</syntaxhighlight>
 
; Aufräumen
Beim Löschen eines Containers bleibt das dazugehörige Volume immer erhalten
* Das ist zweckmäßig, weil sich in Volumes ja Daten befinden, die Sie in zukünftigen Containern vielleicht noch brauchen
Bei diesem Beispiel ist das aber nicht der Fall
* Wir wollen den Container und das Volume löschen
* Deswegen sollten Sie unbedingt vor docker rm mit docker inspect den Namen des zugeordneten Volumes ermitteln! Das gibt Ihnen die Möglichkeit, in der Folge auch das


Aufräumen
; Volume zu löschen


Beim Löschen eines Containers bleibt das dazugehörige Volume immer erhalten.  
<syntaxhighlight lang="bash" highlight="" line copy>
* Das ist zweckmäßig, weil sich in Volumes ja Daten befinden, die Sie in zukünftigen Containern vielleicht noch brauchen.
docker inspect -f '{{
Bei diesem Beispiel ist das aber nicht der Fall.  
Mounts }} ' mariadb - test
* Wir wollen den Container und das Volume löschen.  
* Deswegen sollten Sie unbedingt vor docker rm mit docker inspect den Namen des zugeordneten Volumes ermitteln! Das gibt Ihnen die Möglichkeit, in der Folge auch das Volume zu löschen:
[{ volume d19f5b86 ... ... / var / lib / mysql local true }]
</syntaxhighlight>


docker inspect -f '{{ .
* Mounts }} ' mariadb - test


  [{ volume d19f5b86 ...          ...    / var / lib / mysql local  true }]


<syntaxhighlight lang="bash" highlight="" line copy>
  docker stop mariadb - test
  docker stop mariadb - test
</syntaxhighlight>


<syntaxhighlight lang="bash" highlight="" line copy>
  docker rm mariadb - test
  docker rm mariadb - test
</syntaxhighlight>
<syntaxhighlight lang="bash" highlight="" line copy>
docker volume rm d19f5b86 ..
</syntaxhighlight>


docker volume rm d19f5b86 ...
Sollten Sie den Container bereits gelöscht haben, ohne vorher die zugehörige Volume- ID ermittelt zu haben, ist es schwierig, das Volume zu löschen


Sollten Sie den Container bereits gelöscht haben, ohne vorher die zugehörige Volume- ID ermittelt zu haben, ist es schwierig, das Volume zu löschen.
<syntaxhighlight lang="bash" highlight="" line copy>
* docker volume ls listet
docker volume ls listet
</syntaxhighlight>


zwar alle bekannten Volumes auf, verrät aber nicht, welchem Container diese Volumes zugeordnet sind.
zwar alle bekannten Volumes auf, verrät aber nicht, welchem Container diese Volumes zugeordnet sind
Immerhin können Sie mit docker volume prune alle Volumes löschen, die keinem Container zugeordnet sind.
Immerhin können Sie mit docker volume prune alle Volumes löschen, die keinem Container zugeordnet sind
* Wenn Sie bisher nur mit Docker experimentiert haben, ist das ungefährlich.
* Wenn Sie bisher nur mit Docker experimentiert haben, ist das ungefährlich
* Andernfalls birgt docker volume prune aber die Gefahr in sich, dass Sie Volumes löschen, deren Daten Sie später vielleicht noch brauchen.
* Andernfalls birgt docker volume prune aber die Gefahr in sich, dass Sie Volumes löschen, deren Daten Sie später vielleicht noch brauchen


== Volumes mit Namen ==
== Volumes mit Namen ==
Im vorigen Abschnitt haben Sie Volumes als Mechanismus kennen gelernt, veränderliche Daten eines Containers auszulagern, also losgelöst vom eigenen Container zu speichern.
Im vorigen Abschnitt haben Sie Volumes als Mechanismus kennen gelernt, veränderliche Daten eines Containers auszulagern, also losgelöst vom eigenen Container zu speichern
* Sofern das Image entsprechend konfiguriert ist, kümmert sich Docker nahezu um alles selbst.
* Sofern das Image entsprechend konfiguriert ist, kümmert sich Docker nahezu um alles selbst
* Allerdings haben die automatisch erzeugten Volumes einen gravierenden Nachteil: Sie bekommen als Namen eine zufällige, 64-stellige hexadezimale Zahl.
* Allerdings haben die automatisch erzeugten Volumes einen gravierenden Nachteil: Sie bekommen als Namen eine zufällige, 64-stellige hexadezimale Zahl
* Die vorigen Beispiele haben gezeigt, wie übersichtlich das die weitere Verwaltung bzw. das Löschen von Volumes macht.
* Die vorigen Beispiele haben gezeigt, wie übersichtlich das die weitere Verwaltung bzw. das Löschen von Volumes macht
Zum Glück gibt es einen einfachen Ausweg: Mit einer Option können Sie Volumes eigene Namen zuweisen.
Zum Glück gibt es einen einfachen Ausweg: Mit einer Option können Sie Volumes eigene Namen zuweisen
* Wir verwenden für die folgenden Beispiele weiterhin MariaDB.
* Wir verwenden für die folgenden Beispiele weiterhin MariaDB
* Die Option -v <vname>:<containerdir> ordnet einem Verzeichnis des Containers einen Volume-Namen zu:
 
Die Option -v <vname>:<containerdir> ordnet einem Verzeichnis des Containers einen Volume-Namen zu


<syntaxhighlight lang="bash" highlight="" line copy>
  docker run -d --name mariadb - test \
  docker run -d --name mariadb - test \
  -v myvolume :/ var / lib / mysql \
-v myvolume :/ var / lib / mysql \
  -e MYSQL_RO O T _P A S S W OR D = geheim mariadb
-e MYSQL_RO O T _P A S S W OR D = geheim mariadb
</syntaxhighlight>


An der Anwendung von MariaDB ändert sich nichts.
An der Anwendung von MariaDB ändert sich nichts
* Die Administration des Volumes wird aber einfacher.
* Die Administration des Volumes wird aber einfacher
* docker inspect und docker system df zeigen statt einer ID den Namen des Volumes an:
 
docker inspect -f '{{ .
* Mounts }} ' mariadb - test


docker inspect und docker system df zeigen statt einer ID den Namen des Volumes an
<syntaxhighlight lang="bash" highlight="" line copy>
docker inspect -f '{{
Mounts }} ' mariadb - test
  [{ volume myvolume
  [{ volume myvolume
  / home / kofler /.
/ home / kofler /
* local / share / docker /volumes / myvolume / _data
local / share / docker /volumes / myvolume / _data
  / var / lib / mysql local z true }]
/ var / lib / mysql local z true }]
</syntaxhighlight>


<syntaxhighlight lang="bash" highlight="" line copy>
  docker system df -v
  docker system df -v
..
VOLUME NAME LINKS SIZE
myvolume 1 186.2 MB
</syntaxhighlight>


...
== Container-Update ohne Datenverlust ==
VOLUME NAME            LINKS        SIZE
Die Vorteile von Volumes werden klar, wenn Sie (z.&nbsp;B.&nbsp;nachdem im Docker Hub eine neue Version des MariaDB-Images veröffentlicht wurde) ein Container-Update durchführen möchten
myvolume               1            186.2 MB
* Dazu stoppen und löschen Sie den aktuellen Container, laden mit docker pull das aktuelle Image herunter, erzeugen einen neuen Container und verbinden diesen mit dem schon vorhandenen Volume!
Beachten Sie, dass bei docker run nun die Option -e zur Einstellung des Passworts entfällt
* In myvolume befinden sich nicht nur alle Datenbanken, die Sie bei der bisherigen Nutzung des Containers eingerichtet haben, sondern auch das MariaDB-Passwort


Es muss daher nicht neuerlich konfiguriert werden


Container-Update ohne Datenverlust
<syntaxhighlight lang="bash" highlight="" line copy>
 
  docker stop mariadb - test
 
  docker rm mariadb - test
Die Vorteile von Volumes werden klar, wenn Sie (z.&nbsp;B.&nbsp;nachdem im Docker Hub eine neue Version des MariaDB-Images veröffentlicht wurde) ein Container-Update durchführen möchten.
  docker pull mariadb
* Dazu stoppen und löschen Sie den aktuellen Container, laden mit docker pull das aktuelle Image herunter, erzeugen einen neuen Container und verbinden diesen mit dem schon vorhandenen Volume!
  docker run -d --name mariadb - test \
Beachten Sie, dass bei docker run nun die Option -e zur Einstellung des Passworts entfällt.
-v myvolume :/ var / lib / mysql mariadb
* In myvolume befinden sich nicht nur alle Datenbanken, die Sie bei der bisherigen Nutzung des Containers eingerichtet haben, sondern auch das MariaDB-Passwort.
</syntaxhighlight>
* Es muss daher nicht neuerlich konfiguriert werden.
 
  docker   stop mariadb - test
  docker   rm mariadb - test
  docker   pull mariadb
  docker   run -d --name mariadb - test \
  -v myvolume :/ var / lib / mysql mariadb


Aufräumen
; Aufräumen
Auch das Aufräumen gelingt mit benannten Volumes wesentlich einfacher
* Natürlich sollten Sie das Volume nur löschen, wenn Sie die darin enthaltenen Daten nicht mehr brauchen


Auch das Aufräumen gelingt mit benannten Volumes wesentlich einfacher.
Für die weiteren Beispiele dieses Kapitels ist das Volume aber nicht erforderlich – wir werden bei nächster Gelegenheit ein neues erzeugen
* Natürlich sollten Sie das Volume nur löschen, wenn Sie die darin enthaltenen Daten nicht mehr brauchen.
* Für die weiteren Beispiele dieses Kapitels ist das Volume aber nicht erforderlich – wir werden bei nächster Gelegenheit ein neues erzeugen.


<syntaxhighlight lang="bash" highlight="" line copy>
  docker stop mariadb - test
  docker stop mariadb - test
  docker rm mariadb - test
  docker rm mariadb - test
  docker volume rm myvolume
  docker volume rm myvolume
</syntaxhighlight>


=== Volumes in eigenen Verzeichnissen ===
=== Volumes in eigenen Verzeichnissen ===
Egal, ob mit eigenem Namen oder mit einer zufälligen ID: Standardmäßig landen alle Volumes in von Docker oder Podman verwalteten Verzeichnissen bzw. unter macOS in einer virtuellen Maschine bzw. unter Windows in einem WSL-Verzeichnis.
Egal, ob mit eigenem Namen oder mit einer zufälligen ID: Standardmäßig landen alle Volumes in von Docker oder Podman verwalteten Verzeichnissen bzw. unter macOS in einer virtuellen Maschine bzw. unter Windows in einem WSL-Verzeichnis
Es besteht aber auch die Möglichkeit, Volumes in einem eigenen Verzeichnis im lokalen Dateisystem zu speichern.
Es besteht aber auch die Möglichkeit, Volumes in einem eigenen Verzeichnis im lokalen Dateisystem zu speichern
* Das hat den Vorteil, dass Sie losgelöst von Docker auf den Inhalt des Verzeichnisses zugreifen können.
* Das hat den Vorteil, dass Sie losgelöst von Docker auf den Inhalt des Verzeichnisses zugreifen können
* Die folgenden Kommandos zeigen die Kommandoabfolge.
* Die folgenden Kommandos zeigen die Kommandoabfolge
* Die erste Kommandosequenz richtet den Container mit einem lokalen Volume-Verzeichnis ein.
* Die erste Kommandosequenz richtet den Container mit einem lokalen Volume-Verzeichnis ein
* Dabei kommt wieder die Option -v zum Einsatz, diesmal aber in der Form -v <localdir>/<containerdir>:
 
Dabei kommt wieder die Option -v zum Einsatz, diesmal aber in der Form -v <localdir>/<containerdir>


<syntaxhighlight lang="bash" highlight="" line copy>
  mkdir / home / <username >/ varlibmys q l
  mkdir / home / <username >/ varlibmys q l
  docker run -d --name mariadb - test \
  docker run -d --name mariadb - test \
  -e MYSQL_RO OT _ P A SS W O R D =geheim \
  -e MYSQL_RO OT _ P A SS W O R D =geheim \
  -v / home / <username >/ varlibmy sq l /:/ var / lib / mysql mariadb
  -v / home / <username >/ varlibmy sq l /:/ var / lib / mysql mariadb
</syntaxhighlight>


Unter Linux und macOS muss der Pfad zum lokalen Volume-Verzeichnis mit / beginnen.
Unter Linux und macOS muss der Pfad zum lokalen Volume-Verzeichnis mit / beginnen
* Ein relativer Pfad in der Form ./name wird nicht akzeptiert.
* Ein relativer Pfad in der Form ./name wird nicht akzeptiert
* Wenn Sie nur name angeben, betrachtet docker run die Zeichenkette als Volume-Namen.
* Wenn Sie nur name angeben, betrachtet docker run die Zeichenkette als Volume-Namen
* Es erzeugt dann wie im vorigen Abschnitt selbst ein Volume und benennt dieses mit name.
* Es erzeugt dann wie im vorigen Abschnitt selbst ein Volume und benennt dieses mit name


Volumes versus Mounts
== Volumes versus Mounts ==
In der Docker-Dokumentation ist mal von Volumes die Rede, dann wieder von Mounts
Was ist der Unterschied?
Mounts bezeichnet einen Mechanismus zum Einbetten eines externen Dateisystems in den Verzeichnisbaum des Containers
* Es gibt drei Typen von Mounts: bind, volume und tmpfs
* Bei einem Volume handelt es sich – ein wenig verwirrend – um einen bind- Mount
Anstelle der in diesem Buch oft genutzten Option -v bzw. --volume des Kommandos docker run können Sie auch die Option --mount verwenden


In der Docker-Dokumentation ist mal von Volumes die Rede, dann wieder von Mounts.
Aus
Was ist der Unterschied?
<syntaxhighlight lang="bash" highlight="" line copy>
Mounts bezeichnet einen Mechanismus zum Einbetten eines externen Dateisystems in den Verzeichnisbaum des Containers.
* Es gibt drei Typen von Mounts: bind, volume und tmpfs.
* Bei einem Volume handelt es sich – ein wenig verwirrend – um einen bind- Mount.
Anstelle der in diesem Buch oft genutzten Option -v bzw. --volume des Kommandos docker run können Sie auch die Option --mount verwenden.
* Aus
  -v <hostdir>:<containerdir>
  -v <hostdir>:<containerdir>
wird dann:
</syntaxhighlight>
  --mount type=bind,source=<hostdir>,destination=<containerdir>
wird dann
Die langatmige Syntax von --mount ist der Grund, warum wir -v vorziehen.
   
<syntaxhighlight lang="bash" highlight="" line copy>
--mount type=bind,source=<hostdir>,destination=<containerdir>
</syntaxhighlight>
Die langatmige Syntax von --mount ist der Grund, warum wir -v vorziehen


Probleme mit SELinux
== Probleme mit SELinux ==
Bei Fedora, RHEL und damit kompatiblen Distributionen verbietet SELinux Volumes, die sich nicht in den für Docker oder Podman reservierten Verzeichnissen befinden (z.&nbsp;B.&nbsp;/var/lib/docker/volumes )
* Sobald Sie einen eigenen Ort angeben, tritt ein Fehler auf
* Abhilfe schafft das zusätzliche Flag :z oder :Z, das Sie der Volume-Option hinzufügen müssen (also z.&nbsp;B.&nbsp;-v /home/kofler/varlibmysql/:/var/lib/mysql:z)
Beide Flags bewirken, dass den von Docker oder Podman erzeugten Dateien automatisch der erforderliche SELinux-Kontext zugewiesen wird. :z erlaubt eine Nutzung der Dateien durch unterschiedliche Container, während :Z die Dateien speziell dem einen zu startenden Container zuordnet


Bei Fedora, RHEL und damit kompatiblen Distributionen verbietet SELinux Volumes, die sich nicht in den für Docker oder Podman reservierten Verzeichnissen befinden
=== Siehe auch ===
(z.&nbsp;B.&nbsp;/var/lib/docker/volumes ).
Details und Hintergrundinformationen finden Sie hier
* Sobald Sie einen eigenen Ort angeben, tritt ein Fehler auf.
# https://stackoverflow.com/questions/44139279
* Abhilfe schafft das zusätzliche Flag :z oder :Z, das Sie der Volume-Option hinzufügen müssen (also z.&nbsp;B.&nbsp;-v /home/kofler/varlibmysql/:/var/lib/mysql:z).
Beide Flags bewirken, dass den von Docker oder Podman erzeugten Dateien automatisch der erforderliche SELinux-Kontext zugewiesen wird. :z erlaubt eine Nutzung der Dateien durch unterschiedliche Container, während :Z die Dateien speziell dem einen zu startenden Container zuordnet.


Details und Hintergrundinformationen finden Sie hier:
https://stackoverflow.com/questions/44139279


== Probleme auf Windows-Hosts ==
; Grundsätzlich ist die Option -v zur Angabe eines lokalen Volume-Verzeichnisses auch auf Windows-Hosts erlaubt
Dabei sind drei Einschränkungen zu beachten


Probleme auf Windows-Hosts
Die Pfadangabe kann mit dem in Windows unüblichen /-Zeichen erfolgen oder muss in Anführungszeichen gestellt werden, also z.&nbsp;B.&nbsp;so
<syntaxhighlight lang="bash" highlight="" line copy>


-v C :/ Users / name / dir : volumedi r
-v " C :\ Users \ name \ dir ": volumedi r
</syntaxhighlight>


Grundsätzlich ist die Option -v zur Angabe eines lokalen Volume-Verzeichnisses auch auf Windows-Hosts erlaubt.
Lokale Volume-Verzeichnisse sind mit Einschränkungen verbunden, die sich aus den unterschiedlichen internen Strukturen von Windowsund Linux-Dateisystemen ergeben
* Dabei sind drei Einschränkungen zu beachten:
* Manche Dateioperationen funktionieren, andere wiederum nicht
Die Pfadangabe kann mit dem in Windows unüblichen /-Zeichen erfolgen oder
Dateioperationen in lokalen Verzeichnissen sind deutlich langsamer als bei Volumes, die von Docker direkt verwaltet werden
muss in Anführungszeichen gestellt werden, also z.&nbsp;B.&nbsp;so:


-v C :/ Users / name / dir : volumedi r
In den Docker-Foren gibt es eine Menge Threads von Benutzern, die Probleme mit Volume-Verzeichnissen unter Windows haben
-v " C :\ Users \ name \ dir ": volumedi r
* Sie machen sich das Leben einfacher, wenn Sie unter Windows auf Volumes in eigenen Verzeichnissen verzichten
Lokale Volume-Verzeichnisse sind mit Einschränkungen verbunden, die sich aus den unterschiedlichen internen Strukturen von Windowsund Linux-Dateisystemen ergeben.
* Manche Dateioperationen funktionieren, andere wiederum nicht.
Dateioperationen in lokalen Verzeichnissen sind deutlich langsamer als bei Volumes, die von Docker direkt verwaltet werden.
In den Docker-Foren gibt es eine Menge Threads von Benutzern, die Probleme mit Volume-Verzeichnissen unter Windows haben.
* Sie machen sich das Leben einfacher, wenn Sie unter Windows auf Volumes in eigenen Verzeichnissen verzichten.


Aufräumen
; Aufräumen
Beim Stoppen und Löschen des Containers ändert sich nichts


Beim Stoppen und Löschen des Containers ändert sich nichts.
Um das Löschen des Volume-Verzeichnisses müssen Sie sich nun aber selbst kümmern, wobei Sie je nach Betriebssystem rm -rf verz oder rmdir /s verz ausführen
* Um das Löschen des Volume-Verzeichnisses müssen Sie sich nun aber selbst kümmern, wobei Sie je nach Betriebssystem rm -rf verz oder rmdir /s verz ausführen.


<syntaxhighlight lang="bash" highlight="" line copy>
  docker stop mariadb - test
  docker stop mariadb - test
  docker rm   mariadb - test
  docker rm mariadb - test
 
 
  rmdir / s varlibmy s ql               ( Windows )
  rmdir / s varlibmy s ql ( Windows )
  sudo rm -rf varlibmys q l             ( Linux , macOS )
  sudo rm -rf varlibmys q l ( Linux , macOS )
</syntaxhighlight>


Docker bzw. Podman erzeugen bei der Ausführung von Containern Dateien, die nicht Ihrem eigenen Account zugeordnet sind.
Docker bzw. Podman erzeugen bei der Ausführung von Containern Dateien, die nicht Ihrem eigenen Account zugeordnet sind
* Deswegen scheitert das rm-Kommando, wenn Sie sudo vergessen.
* Deswegen scheitert das rm-Kommando, wenn Sie sudo vergessen


{{:Docker/Buch/03 Grundlagen/Kommunikation zwischen Containern}}
{{:Docker/Buch/03 Grundlagen/Kommunikation zwischen Containern}}
Zeile 406: Zeile 477:
[[Kategorie:Docker/Buch/03 Grundlagen]]
[[Kategorie:Docker/Buch/03 Grundlagen]]
</noinclude>
</noinclude>
[[Kategorie:Docker/Volume]]

Aktuelle Version vom 13. November 2026, 12:29 Uhr

Docker/Buch/03 Grundlagen/05 Volumes - Datenspeicherung in Volumes

Beschreibung

Wie und wo werden Container Daten gespeichert?

  • Was würde sich besser zur Beantwortung dieser Fragen eignen als ein Container mit einem Datenbankserver?
  • Wir haben uns hier für das mit MySQL kompatible Datenbanksystem MariaDB entschieden

Sie werden sehen, Sie müssen kein Datenbankexperte sein, um dem Beispiel folgen zu können

Siehe auch

Im Docker Hub gibt es für die Datenbankserver MySQL und MariaDB diverse Images

Für diesen Abschnitt haben wir mit dem offiziellen MariaDB-Image gearbeitet

Es ist auf der folgenden Seite dokumentiert

Beim Einrichten des Containers mit dem folgenden Kommando wird das root- Passwort für den Datenbankserver als Parameter übergeben

  • Das ist kein optimaler Mechanismus, weil das Passwort kurz im Klartext in der Prozessliste für alle sichtbar ist
  • Eine bessere Vorgehensweise präsentieren wir Ihnen in Abschnitt 5.4, »Passwörter und andere Geheimnisse«
  • Der Inhalt von MYSQL_ROOT_PASSWORD kann später auch mit docker inspect mariadb-test ausgelesen werden – allerdings nur von Anwendern, die selbst docker ausführen dürfen

Anstelle von MYSQL_ROOT_PASSWORD können Sie die gleichwertige Variable MARIADB_ROOT_PASSWORD verwenden

Wir bleiben her bei MYSQL_xxx , weil diese Variablennamen universell für MariaDB- und für MySQL-Images funktionieren

 docker run -d --name mariadb - test \
 -e MYSQL_RO O T _P A S S W OR D = geheim mariadb

Wenn Sie Podman verwenden, müssen Sie für MariaDB docker.io als Image-Registry auswählen

  • Die interaktive Auswahl vermeiden Sie, indem Sie gleich den vollständigen Image-Namen angeben

Dieser funktioniert natürlich auch in Kombination mit docker

 podman run -d --name mariadb - test \
 -e MYSQL_ROO T _ P AS S W O R D = geheim docker.io /library / mariadb

Das Kommando docker run gibt zwar die ID des neuen Containers aus, zeigt aber ansonsten keine Statusinformationen an, die auf einen erfolgreichen Start hinweisen

Sie können sich mit docker ps davon überzeugen, dass der Container wirklich läuft

 docker ps
 CONTAINE R ID ... COMMAND CREATED NAMES
 02 f5b1017a b b mysqld 52 seconds ago mariadb -test
 ..

Sollte docker ps keine Ausgaben liefern bzw. sollte mariadb-test in der Liste der aktiven Container fehlen, ergründen Sie am besten mit docker logs die Fehlerursache Wenn Sie beispielsweise vergessen haben, das gewünschte Passwort mit der Option -e zu übergeben, erhalten Sie mit docker logs die folgende Fehlermeldung

 docker logs mariadb - test
 Entrypoi n t script for MariaDB Server 1:11.0.2 + maria ~ ubu2204
 Switchin g to dedicate d user 'mysql '
 Database is uninitia l i ze d and password option is not specifie d
 You need to specify one of MARIADB_ROOT_P AS SW OR D ,
 MARIADB_ R O O T_ P A S SW O R D _ HA S H ..

Beachten Sie, dass Sie vor einem neuerlichen Start den zuletzt erzeugten Container löschen, also docker rm mariadb-test ausführen müssen

Mehrzeilige Kommandos

Wenn wir in diesem Buch Kommandos aus Platzgründen über zwei Zeilen verteilen müssen, kennzeichnen wir das Ende der umgebrochenen Zeile mit dem Zeichen \

  • Unter Linux und macOS haben Sie nun die Wahl, ob Sie das Kommando einfach in einer Zeile eingeben oder ob Sie das Kommando wie im Buch abgedruckt mehrzeilig samt aller \-Zeichen eingeben

Beachten Sie aber, dass mehrzeilige Kommandos in der PowerShell unter Windows mit dem Zeichen ` zu trennen sind!

PowerShell

In der PowerShell müssten Sie das obige Kommando daher entweder in einer langen Zeile oder wie folgt eingeben

 docker run -d --name mariadb-test -e MYSQL_ROOT_PASSWORD=geheim mariadb

Wenn der Start erfolgreich war, läuft der Datenbankserver wegen der Option -d im Hintergrund weiter, bis der Container explizit wieder gestoppt wird

 docker stop mariadb - test

Speicherung der Datenbank in einem automatisch erzeugten Volume MariaDB speichert grundsätzlich alle Datenbankdateien im Verzeichnis /var/lib/ mysql

  • Im Dockerfile von MariaDB, also in der Beschreibung des Images, ist /var/

lib/mysql aber als Volume gekennzeichnet

  • Das bedeutet, dass dieses Verzeichnis außerhalb des Containers angelegt wird

Unter Linux richtet Docker dazu ein Unterverzeichnis innerhalb von

 /var/lib/docker/volumes

auf dem Host-Rechner ein

Wenn Sie mit Rootless Docker arbeiten, landet das Unterverzeichnis entsprechend in .local/share/docker/ volumes

  • Podman verwendet das Verzeichnis .local/share/containers/storage/ volumes
  • Den genauen Verzeichnisnamen können Sie mit docker inspect mariadb-test ermitteln, wenn Sie in der mehrseitigen Ausgabe dieses Kommandos nach Mounts suchen

Unter Windows und macOS ist die Funktionsweise ganz ähnlich, allerdings wird das Volume-Verzeichnis nicht direkt im Dateisystem von Windows bzw. macOS eingerichtet, sondern innerhalb der virtuellen Maschine des Linux-Kernels, der für die Ausführung der Docker Engine zuständig ist

  • Das verstärkt den »Blackbox- Charakter« derartiger Volumes

Was haben Sie davon, dass Docker zwischen Daten differenziert, die im Container gespeichert werden, und solchen, die außerhalb (also in einem Volume) landen? Vorerst nicht viel

  • Sowohl die Container als auch die Volumes landen in einem von

Docker verwalteten Verzeichnis (z. B. /var/lib/docker), auf dessen Inhalt Sie in keinem Fall direkt zugreifen sollten Aber mit Volumes haben Sie die Möglichkeit, die Daten eines beendeten Containers später in einen neuen Container zu übernehmen

  • Das ist z. B. dann sinnvoll, wenn Sie nach einem MariaDB-Update den vorhandenen Container löschen und durch einen neuen Container mit der aktuellen MariaDB-Version ersetzen möchten
  • Bei einem derartigen Update wollen Sie natürlich Ihre Daten nicht verlieren

Außerdem werden Sie im nächsten Abschnitt lernen, wie Sie Volumes mit eigenen, lokalen Verzeichnissen verbinden und so gewissermaßen aus der Docker-Blackbox herauslösen können

Volumes analysieren

Das Kommando docker inspect liefert in einem mehr als 100 Zeilen langen Listing unzählige Details zu einem bestimmten Container

Uns interessieren an dieser Stelle vor allem die Volume-Daten

 docker inspect mariadb - test
 ..
 " Mounts ": [
 {
 " Type ": "volume " ,
 " Name ": "d19f5b86 ..." ,
 " Source ": "/ home / kofler /local / share / docker / volumes /\
 d19f5b86 .../ _data " ,
 " Destinati o n ": "/ var /lib / mysql " ,
 " Driver ": " local " ,
 " Mode ": "" ,
 " RW ": true ,
 " Propagati o n ": ""
 }
 ],
 ..

Der Container mariadb-test ist also einem Volume mit der ID d19f5b86..

  • zugeordnet

Dieses Volume befindet sich physikalisch im folgenden Verzeichnis

 / home / kofler / local / share / docker / volumes / d19f5b86 .../ _data

Anstatt die Volume-Daten mühsam aus dem Listing zu extrahieren, können Sie an docker inspect eine Formatoption übergeben und nur die für Sie relevanten Daten – in diesem Fall alle Mounts – herausfiltern

 docker inspect -f '{{ 
 Mounts }} ' mariadb - test

 [{ volume d19f5b86 ..
 / home / kofler / local / share / docker /volumes / d19f5b86 .../ _data
 / var / lib / mysql
 local
 true }]

Sobald Sie den Namen eines Volumes kennen (hier d19f5b86...), können Sie mit docker volume inspect weitere Informationen herausfinden. (Beachten Sie, dass Sie dabei den gesamten, 64 Zeichen langen hexadezimalen Code angeben müssen

Wir geben in den Listings dieses Abschnitts zur besseren Übersichtlichkeit jeweils nur die ersten 8 Stellen an.)

 docker volume inspect d19f5b86 ..
 [
 {
 " CreatedAt ": "2023 -05 -14 T18 :06:16+02:00" ,
 " Driver ": " local " ,
 " Labels ": null ,
 " Mountpoin t ": "/ home /kofler / local / share / docker /\
 volumes / d19f5b86 .../ _data " ,
 " Name ": "d19f5b86 .." ,
 " Options ": null ,
 " Scope ": " local "
 }
 ]

Leider verrät docker volume inspect nicht, wie groß ein Volume ist

  • Diese Information liefert docker system df, allerdings nicht spezifisch für ein Volume, sondern global für alle durch Docker verwalteten Images, Container, Volumes etc
  • Dementsprechend ist die Ausgabe von docker system df zumeist recht lang

Wir haben aus dem folgenden Listing alle Informationen entfernt, die nichts mit unserem Volume zu tun haben

 docker system df -v
 Images space usage : ..
 Containe r s space usage : ..
 Build cache usage : ..
 Local Volumes space usage 
 VOLUME NAME LINKS SIZE
 d19f5b86 ... 1 186.2 MB

Vielleicht fragen Sie sich, warum das Volume derart groß ist: Wir haben ja noch gar keine Datenbanken erzeugt und mit Daten befüllt

  • Die Volume-Größe hat mit einer

Eigenheit des MariaDB-Servers zu tun: Beim ersten Start werden Dateien eingerichtet, in denen später Datenbanken, Transaktionen usw

  • gespeichert werden
  • Die minimale Größe dieser Dateien ist bereits ziemlich beträchtlich

MariaDB-Client aufrufen

Bevor wir Ihnen im nächsten Abschnitt mehr Details zum effizienten Umgang mit Volumes verraten, möchten wir Ihnen kurz zeigen, wie Sie den MariaDB-Container ansehen bzw. analysieren können

  • Das ist insofern nicht ganz trivial, als eine interaktive Nutzung des Containers nicht vorgesehen ist
  • Sie können aber mit docker exec innerhalb des im Hintergrund laufenden Containers das interaktive Kommando mariadb starten. (mariadb ist ein Kommando, mit dem Sie SQL-Anweisungen auf einem MariaDB-Server ausführen können
  • Falls Sie einen Container mit einem MySQL- Server ausführen, lautet der Kommandoname entsprechend mysql.)

Als Login-Passwort geben Sie das gleiche Passwort wie beim Erzeugen des Containers an

Wenn Sie die vorherigen Kommandos exakt nachvollzogen haben, lautet es geheim

 docker exec -it mariadb - test mariadb -u root -p
 Enter password : ******** ( root - Passwort fü r MariaDB )
 Welcome to the MariaDB monitor 
 Server version : 11.0.2 -MariaDB

 MariaDB [( none ) ] > show status ;
 ..
 
 MariaDB [( none ) ] > exit
Ein Blick in den Container

Wenn Sie neugierig sind und weitere Details über den Container ermitteln möchten, starten Sie parallel zum MariaDB-Server mit docker exec einen bash-Prozess für den Container


docker exec -it mariadb - test / bin / bash
 
 root@34d e 8 6 6b f f 1 2 :/# cat / etc / os - release
 PRETTY_N A ME =" Ubuntu 24.04.2 LTS "
 ..
 
 root@34d e 8 6 6b f f 1 2 :/# ps -ax
 PID TTY STAT TIME COMMAND
 1 ? Ssl 0:00 mysqld
 147 ? Ss 0:00 / bin / bash
 218 ? R+ 0:00 ps -ax
 
 root@34d e 8 6 6b f f 1 2 :/# mariadbd --version
 mariadbd Ver 11.0.2 -MariaDB -1:11.0. 2 + maria ~ ubu2204 for
 debian - linux - gnu on x86_64 ( mariadb 
 org binary distribu t io n )
 
 root@34d e 8 6 6b f f 1 2 :/# exit

Anhand von cat /etc/os-release wissen Sie nun, dass MariaDB Ubuntu als Basis- Image verwendet

Logging

Da der MariaDB-Container im Hintergrund läuft, sehen Sie im Terminal weder Fehlermeldungen noch Logging-Ausgaben

Diese können Sie mit docker logs lesen

 docker logs mariadb - test
 
 Starting MariaDB 11.0.2 -MariaDB -1 as process 1
 InnoDB : Compress ed tables use zlib 1.2.11
 InnoDB : Number of transact i o n pools : 1
 InnoDB : Using crc32 + pclmulqdq instruct io n s
 ..
Aufräumen

Beim Löschen eines Containers bleibt das dazugehörige Volume immer erhalten

  • Das ist zweckmäßig, weil sich in Volumes ja Daten befinden, die Sie in zukünftigen Containern vielleicht noch brauchen

Bei diesem Beispiel ist das aber nicht der Fall

  • Wir wollen den Container und das Volume löschen
  • Deswegen sollten Sie unbedingt vor docker rm mit docker inspect den Namen des zugeordneten Volumes ermitteln! Das gibt Ihnen die Möglichkeit, in der Folge auch das
Volume zu löschen
 docker inspect -f '{{ 
 Mounts }} ' mariadb - test
 
 [{ volume d19f5b86 ... ... / var / lib / mysql local true }]


 docker stop mariadb - test


 docker rm mariadb - test


 docker volume rm d19f5b86 ..

Sollten Sie den Container bereits gelöscht haben, ohne vorher die zugehörige Volume- ID ermittelt zu haben, ist es schwierig, das Volume zu löschen

 docker volume ls listet

zwar alle bekannten Volumes auf, verrät aber nicht, welchem Container diese Volumes zugeordnet sind Immerhin können Sie mit docker volume prune alle Volumes löschen, die keinem Container zugeordnet sind

  • Wenn Sie bisher nur mit Docker experimentiert haben, ist das ungefährlich
  • Andernfalls birgt docker volume prune aber die Gefahr in sich, dass Sie Volumes löschen, deren Daten Sie später vielleicht noch brauchen

Volumes mit Namen

Im vorigen Abschnitt haben Sie Volumes als Mechanismus kennen gelernt, veränderliche Daten eines Containers auszulagern, also losgelöst vom eigenen Container zu speichern

  • Sofern das Image entsprechend konfiguriert ist, kümmert sich Docker nahezu um alles selbst
  • Allerdings haben die automatisch erzeugten Volumes einen gravierenden Nachteil: Sie bekommen als Namen eine zufällige, 64-stellige hexadezimale Zahl
  • Die vorigen Beispiele haben gezeigt, wie übersichtlich das die weitere Verwaltung bzw. das Löschen von Volumes macht

Zum Glück gibt es einen einfachen Ausweg: Mit einer Option können Sie Volumes eigene Namen zuweisen

  • Wir verwenden für die folgenden Beispiele weiterhin MariaDB

Die Option -v <vname>:<containerdir> ordnet einem Verzeichnis des Containers einen Volume-Namen zu

 docker run -d --name mariadb - test \
 -v myvolume :/ var / lib / mysql \
 -e MYSQL_RO O T _P A S S W OR D = geheim mariadb

An der Anwendung von MariaDB ändert sich nichts

  • Die Administration des Volumes wird aber einfacher

docker inspect und docker system df zeigen statt einer ID den Namen des Volumes an

 docker inspect -f '{{ 
 Mounts }} ' mariadb - test
 
 [{ volume myvolume
 / home / kofler /
 local / share / docker /volumes / myvolume / _data
 / var / lib / mysql local z true }]
 docker system df -v
 ..
 VOLUME NAME LINKS SIZE
 myvolume 1 186.2 MB

Container-Update ohne Datenverlust

Die Vorteile von Volumes werden klar, wenn Sie (z. B. nachdem im Docker Hub eine neue Version des MariaDB-Images veröffentlicht wurde) ein Container-Update durchführen möchten

  • Dazu stoppen und löschen Sie den aktuellen Container, laden mit docker pull das aktuelle Image herunter, erzeugen einen neuen Container und verbinden diesen mit dem schon vorhandenen Volume!

Beachten Sie, dass bei docker run nun die Option -e zur Einstellung des Passworts entfällt

  • In myvolume befinden sich nicht nur alle Datenbanken, die Sie bei der bisherigen Nutzung des Containers eingerichtet haben, sondern auch das MariaDB-Passwort

Es muss daher nicht neuerlich konfiguriert werden

 docker stop mariadb - test
 docker rm mariadb - test
 docker pull mariadb
 docker run -d --name mariadb - test \
 -v myvolume :/ var / lib / mysql mariadb
Aufräumen

Auch das Aufräumen gelingt mit benannten Volumes wesentlich einfacher

  • Natürlich sollten Sie das Volume nur löschen, wenn Sie die darin enthaltenen Daten nicht mehr brauchen

Für die weiteren Beispiele dieses Kapitels ist das Volume aber nicht erforderlich – wir werden bei nächster Gelegenheit ein neues erzeugen

 docker stop mariadb - test
 docker rm mariadb - test
 docker volume rm myvolume

Volumes in eigenen Verzeichnissen

Egal, ob mit eigenem Namen oder mit einer zufälligen ID: Standardmäßig landen alle Volumes in von Docker oder Podman verwalteten Verzeichnissen bzw. unter macOS in einer virtuellen Maschine bzw. unter Windows in einem WSL-Verzeichnis Es besteht aber auch die Möglichkeit, Volumes in einem eigenen Verzeichnis im lokalen Dateisystem zu speichern

  • Das hat den Vorteil, dass Sie losgelöst von Docker auf den Inhalt des Verzeichnisses zugreifen können
  • Die folgenden Kommandos zeigen die Kommandoabfolge
  • Die erste Kommandosequenz richtet den Container mit einem lokalen Volume-Verzeichnis ein

Dabei kommt wieder die Option -v zum Einsatz, diesmal aber in der Form -v <localdir>/<containerdir>

 mkdir / home / <username >/ varlibmys q l
 docker run -d --name mariadb - test \
 -e MYSQL_RO OT _ P A SS W O R D =geheim \
 -v / home / <username >/ varlibmy sq l /:/ var / lib / mysql mariadb

Unter Linux und macOS muss der Pfad zum lokalen Volume-Verzeichnis mit / beginnen

  • Ein relativer Pfad in der Form ./name wird nicht akzeptiert
  • Wenn Sie nur name angeben, betrachtet docker run die Zeichenkette als Volume-Namen
  • Es erzeugt dann wie im vorigen Abschnitt selbst ein Volume und benennt dieses mit name

Volumes versus Mounts

In der Docker-Dokumentation ist mal von Volumes die Rede, dann wieder von Mounts Was ist der Unterschied? Mounts bezeichnet einen Mechanismus zum Einbetten eines externen Dateisystems in den Verzeichnisbaum des Containers

  • Es gibt drei Typen von Mounts: bind, volume und tmpfs
  • Bei einem Volume handelt es sich – ein wenig verwirrend – um einen bind- Mount

Anstelle der in diesem Buch oft genutzten Option -v bzw. --volume des Kommandos docker run können Sie auch die Option --mount verwenden

Aus

 -v <hostdir>:<containerdir>

wird dann

--mount type=bind,source=<hostdir>,destination=<containerdir>

Die langatmige Syntax von --mount ist der Grund, warum wir -v vorziehen

Probleme mit SELinux

Bei Fedora, RHEL und damit kompatiblen Distributionen verbietet SELinux Volumes, die sich nicht in den für Docker oder Podman reservierten Verzeichnissen befinden (z. B. /var/lib/docker/volumes )

  • Sobald Sie einen eigenen Ort angeben, tritt ein Fehler auf
  • Abhilfe schafft das zusätzliche Flag :z oder :Z, das Sie der Volume-Option hinzufügen müssen (also z. B. -v /home/kofler/varlibmysql/:/var/lib/mysql:z)

Beide Flags bewirken, dass den von Docker oder Podman erzeugten Dateien automatisch der erforderliche SELinux-Kontext zugewiesen wird. :z erlaubt eine Nutzung der Dateien durch unterschiedliche Container, während :Z die Dateien speziell dem einen zu startenden Container zuordnet

Siehe auch

Details und Hintergrundinformationen finden Sie hier

  1. https://stackoverflow.com/questions/44139279


Probleme auf Windows-Hosts

Grundsätzlich ist die Option -v zur Angabe eines lokalen Volume-Verzeichnisses auch auf Windows-Hosts erlaubt

Dabei sind drei Einschränkungen zu beachten

Die Pfadangabe kann mit dem in Windows unüblichen /-Zeichen erfolgen oder muss in Anführungszeichen gestellt werden, also z. B. so

 -v C :/ Users / name / dir : volumedi r
 -v " C :\ Users \ name \ dir ": volumedi r

Lokale Volume-Verzeichnisse sind mit Einschränkungen verbunden, die sich aus den unterschiedlichen internen Strukturen von Windowsund Linux-Dateisystemen ergeben

  • Manche Dateioperationen funktionieren, andere wiederum nicht

Dateioperationen in lokalen Verzeichnissen sind deutlich langsamer als bei Volumes, die von Docker direkt verwaltet werden

In den Docker-Foren gibt es eine Menge Threads von Benutzern, die Probleme mit Volume-Verzeichnissen unter Windows haben

  • Sie machen sich das Leben einfacher, wenn Sie unter Windows auf Volumes in eigenen Verzeichnissen verzichten
Aufräumen

Beim Stoppen und Löschen des Containers ändert sich nichts

Um das Löschen des Volume-Verzeichnisses müssen Sie sich nun aber selbst kümmern, wobei Sie je nach Betriebssystem rm -rf verz oder rmdir /s verz ausführen

 docker stop mariadb - test
 docker rm mariadb - test
  
 rmdir / s varlibmy s ql ( Windows )
 sudo rm -rf varlibmys q l ( Linux , macOS )

Docker bzw. Podman erzeugen bei der Ausführung von Containern Dateien, die nicht Ihrem eigenen Account zugeordnet sind

  • Deswegen scheitert das rm-Kommando, wenn Sie sudo vergessen

Docker/Buch/03 Grundlagen/Kommunikation zwischen Containern

Docker/Buch/03 Grundlagen/Administration