Docker/Buch/03 Grundlagen/Volumes
Volumes
- Datenspeicherung in Volumes
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. (Mehr Tipps zum praktischen Einsatz von MySQL und MariaDB folgen in Abschnitt 10.1.)
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 in diesem Kapitel 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 umbrochenen 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! 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.
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:
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.
Kommunikation zwischen mehreren Containern
Für viele Container-Anwendungen gilt: Ein Container kommt selten allein! Sobald aber mehrere Container gleichzeitig ausgeführt werden, stellt sich die Frage, wie sie miteinander kommunizieren.
- Das gelingt am einfachsten über ein internes Netzwerk, das Sie mit docker network einrichten.
Die in diesem Abschnitt vorgestellten Kommandos zeigen die Kombination von drei Containern mit MariaDB, phpMyAdmin und WordPress.
- Die Beispiele funktionieren unverändert auch mit Rootless Docker und mit Podman.
Mehr Komfort mit »compose«
Wir zeigen Ihnen hier das manuelle Einrichten eines Docker-Netzwerks sowie mehrerer Container primär aus didaktischen Gründen.
- Wir wollen, dass Sie verstehen, wie Docker funktioniert.
In der Praxis ist es wesentlich effizienter, derartige Setups mit den Kommandos docker compose bzw. podman-compose zu bewerkstelligen.
- Wie Sie dazu vorgehen, lernen Sie in Kapitel 5, »Container-Setups mit compose«.
Privates Docker-Netzwerk einrichten
Das Einrichten eines Docker-Netzwerks ist denkbar einfach:
docker network create testnet
MariaDB
Schon deutlich komplizierter ist der Start des Datenbanksystems.
- Die Verwendung von MariaDB ist Ihnen ja aus den bisherigen Beispielen prinzipiell vertraut.
- Diesmal ändern sich aber ein paar Details:
Wir möchten, dass MariaDB beim ersten Start eine leere Datenbank (wp) sowie einen neuen Account (wpuser) samt Passwort anlegt.
- Auf diesen Account erhalten später phpMyAdmin und WordPress Zugriff.
- Das MariaDB-Image kümmert sich um die notwendigen Initialisierungsarbeiten, wenn Sie die Variablen MYSQL_DATABASE , MYSQL_USER und MYSQL_PASSWORD mit -e an docker run übergeben.
Für das Beispiel ist es nicht erforderlich, dass das root-Passwort von MariaDB den anderen Containern bekannt ist.
- Dank -e MYSQL_RANDOM_ROOT_PASSWORD=1 verwendet MariaDB einfach ein zufälliges Passwort.
Neu ist auch die Option --network , die den Container mit dem vorhin erzeugten Netzwerk verbindet.
Somit ergibt sich eine schon etwas komplexere Abfolge von Optionen für den Start des MariaDB-Containers:
docker run -d --name mariadb - test \ -h mariadb - test --network testnet \ -e MYSQL_RA ND O M _ RO O T _ P AS S W O R D =1 \ -e MYSQL_DA TA B A S E = wp \ -e MYSQL_US ER = wpuser \ -e MYSQL_PA SS W O R D = geheim \ -v myvolume :/ var /lib / mysql \ mariadb
phpMyAdmin
phpMyAdmin ist eine populäre Weboberfläche zur Administration von MariaDB
(siehe Abbildung 3.2).
Abbildung 3.2 phpMyAdmin und der MariaDB-Server laufen in zwei voneinander getrennten Containern.
Der Start des entsprechenden Containers gelingt unkompliziert:
docker run -d --name pma \ --network testnet \ -p 8080:80 \ -e PMA_HOST =mariadb - test \ phpmyadm i n / phpmyadmi n
Ein paar Anmerkungen zu den Optionen
Die Option --network verbindet auch diesen Container mit dem privaten Netzwerk dieses Beispiels. -p bewirkt, dass die Weboberfläche (Port 80 im Container) auf dem Host-System unter Port 8080 angesprochen werden kann. Dank der Variablen PMA_HOST weiß der phpMyAdmin-Container, unter welchem Host-Namen der MariaDB-Server im Netzwerk läuft.
- Docker-Netzwerke kümmern sich automatisch um die netzwerkinterne Namensauflösung, wobei die mit --name angegebenen Namen gelten.
Wie MariaDB wird auch der phpMyAdmin-Container im Hintergrund ausgeführt (Option -d).
- Um zu testen, ob alles funktioniert, öffnen Sie im Webbrowser Ihres Rechners die Adresse localhost:8080.
- Sie müssen sich beim Datenbankserver mit dem Accountnamen wpuser und dem Passwort geheim anmelden.
- Danach können Sie über die Weboberfläche die in den Tabellen enthaltenen Daten abfragen, neue Tabellen einrichten usw.
root-Zugriff in phpMyAdmin
Wenn Sie in phpMyAdmin nicht nur die Datenbank wp, sondern alle Datenbanken von MariaDB sehen wollen, müssen Sie beim Start des MariaDB-Containers wie in den bisherigen Abschnitten ein root-Passwort festlegen.
- Dann gelingt in php- MyAdmin der Login mit root und dem dazugehörigen Passwort.
- In diesem Beispiel ist das nicht möglich, weil das root-Passwort wegen der Variablen MYSQL_RANDOM_
ROOT_PASSWORD=1 zufällig bestimmt wurde.
WordPress
Wie lange haben Sie das letzte Mal gebraucht, um auf einem Server WordPress zu installieren? Wenn Sie das regelmäßig machen, vermutlich nur ein paar Minuten – aber beim ersten Mal dauert es oft viel länger, bis das Fundament, das aus Apache, PHP und MySQL oder MariaDB besteht, mit all seinen Zusatzpaketen installiert und konfiguriert ist. Deutlich schneller geht es mit Docker.
- Einmal vorausgesetzt, dass Sie bereits einen MySQL- oder MariaDB-Container eingerichtet haben, ist zur Inbetriebnahme von WordPress lediglich das folgende, zugegebenermaßen nicht ganz kurze Kommando notwendig:
docker run -d --name wordpress -test \ --network testnet \ -h wordpress - test \ -v wp -html :/ var / www / html / wp - content \ -p 8081:80 \ -e WORDPRES S_ D B _ HO S T = mariadb -test \ -e WORDPRES S_ D B _ US E R = wpuser \ -e WORDPRES S_ D B _ NA M E = wp \ -e WORDPRES S_ D B _ PA S S W O RD = geheim \ wordpres s
Unter der Adresse http://localhost:8081 nehmen Sie die Website nun in Betrieb (siehe Abbildung 3.3).
- Die Anfangskonfiguration beschränkt sich auf zwei Dialoge: Auf der ersten Seite wählen Sie die gewünschte Sprache aus, auf der zweiten Seite richten Sie den WordPress-Administrator ein.
- Die oft heikle Konfiguration der Zugangsdaten
des Datenbankservers entfällt: Darum hat sich ein Script des WordPress-Containers bereits gekümmert.
Abbildung 3.3 WordPress komplettiert das Beispiel in einem dritten Container.
Nur zur Erklärung der docker-run-Optionen
-d bewirkt den Start des Containers als Hintergrunddienst. --name gibt dem Container seinen Namen. --network testnet sorgt dafür, dass der WordPress-Container im gleichen Netzwerk wie der MariaDB-Server und phpMyAdmin läuft. -v macht aus /var/www/html/wp-content ein Volume mit dem Namen wp-html.
- In diesem Verzeichnis werden hochgeladene Bilder, Plugins etc.
- gespeichert, also alle Daten, die nichts mit der eigentlichen WordPress-Installation zu tun haben.
Der Volume-Name erleichtert die weitere Administration des Containers, z. B. bei Updates oder beim Löschen.
- Alle hochgeladenen Dateien und Erweiterungen bleiben dabei im Volume erhalten.
Mit -p geben Sie an, unter welchem Port die WordPress-Installation auf dem Docker-Host angesprochen werden kann.
- Da Port 8080 im vorigen Beispiel schon für phpMyAdmin zum Einsatz kam, haben wir jetzt eben 8081 verwendet.
- Sofern Sie Docker mit root-Rechten ausführen und auf Ihrem Host-Rechner Port 80 frei ist, können Sie natürlich auch -p 80:80 angeben.
Die Variablen WORDPRESS_DB_HOST , _USER, _PASSWORD und _NAME geben an, unter welchem Host-Namen der MySQL- oder MariaDB-Server läuft, welcher Login-Name und welches Passwort beim Verbindungsaufbau verwendet werden sollen und wie der Name der Datenbank lautet.
- Diese Datenbank muss bereits existieren. (Im Gegensatz zu früheren Versionen des WordPress-Images wird die Datenbank nicht erzeugt.)
Als Host-Namen müssen Sie den Namen (Option --name) des MariaDB-Containers angeben.
- Die Loginund Datenbank-Namen müssen mit den Angaben übereinstimmen, die Sie beim Start von MariaDB mit den Optionen MYSQL_USER , MYSQL_PASSWORD und MYSQL_DATABASE verwendet haben.
Weitere Umgebungsvariablen des offiziellen WordPress-Images sind hier dokumentiert:
Docker-Baukasten
Es ist uns an dieser Stelle nur darum gegangen, einfache Beispiele zu präsentieren, die den Einsatz von Docker zeigen.
- Deutlich mehr Details zur praktischen Nutzung von Webservern (Apache, Nginx), Datenbanksystemen (MariaDB, MySQL etc.), Webapplikationen (WordPress, Joomla, Nextcloud etc.) folgen in Teil II dieses Buchs, in dem wir Ihnen eine Menge Docker-Images vorstellen.
- Diese Images sind wie ein Baukasten, aus dem Sie Ihre eigenen Applikationen zusammenstellen können.
Container stoppen und neu starten
Wenn Sie die drei Container vorübergehend nicht mehr brauchen, können Sie sie stoppen und dann bei Bedarf wieder neu starten.
- Erfreulicherweise können Sie an docker stop bzw. docker start mehrere Container-Namen auf einmal übergeben.
docker stop mariadb - test pma wordpress - test ... docker start mariadb - test pma wordpress - test
Updates
Wenn es von MariaDB, phpMyAdmin und WordPress neue Images gibt, können Sie wie folgt eine Neuinstallation durchführen:
docker stop mariadb - test pma wordpress - test docker rm mariadb - test pma wordpress - test
docker pull mariadb docker pull phpmyadmi n / phpmyadmi n docker pull wordpress
docker run -d --name mariadb - test \ -h mariadb - test \ --network testnet \ -v myvolume :/ var /lib / mysql mariadb
docker run -d --name pma --network testnet \ -p 8080:80 \ -e PMA_HOST =mariadb - test \ phpmyadm i n / phpmyadmi n
docker run -d --name wordpress -test \ --network testnet \ -h wordpress - test \ -v wp -html :/ var / www / html / wp - content \ -p 8081:80 \ -e WORDPRES S_ D B _ HO S T = mariadb -test \ -e WORDPRES S_ D B _ US E R = wpuser \ -e WORDPRES S_ D B _ NA M E = wp \ -e WORDPRES S_ D B _ PA S S W O RD = geheim \ wordpres s
Im Vergleich zur Erstinstallation fällt docker run für MariaDB deutlich kürzer aus, weil die vorhandene Datenbank sowie alle Passwörter weitergenutzt werden.
- Diese Daten befinden sich in myvolume.
Bei phpMyAdmin bleibt docker run unverändert.
- Erstaunlicherweise gilt dies auch für den Start des WordPress-Containers.
- Hier hätte man ja annehmen können, dass die Konfigurationsdaten ebenfalls dauerhaft im Volume gespeichert wären.
- Tatsächlich enthält die entscheidende Konfigurationsdatei wp_config.php aber Code, der die Umgebungsvariablen auswertet.
- Fehlen die Umgebungsvariablen, scheitert der Verbindungsaufbau zwischen WordPress und dem Datenbankserver.
Dank der Wiederverwendung der Volumes bleiben bei dem Update alle Daten (also die Tabellen der wp-Datenbank, Blog-Beiträge in WordPress etc.) erhalten.
Aufräumen
Wenn Sie sämtliche Komponenten dieses Beispiels löschen wollen, also das Netzwerk sowie die Container, Volumes und Images, dann führen Sie die folgenden Kommandos aus:
docker stop mariadb - test pma wordpress - test docker rm mariadb - test pma wordpress - test docker volume rm myvolume docker volume rm wp - html docker network rm testnet docker image rm mariadb wordpress phpmyadm in / phpmyadm i n
Administration
Dieser Abschnitt gibt einen ersten Überblick über Kommandos, mit denen Sie Ihr Container-System administrieren können.
- Zu solchen Verwaltungsaufgaben zählen beispielsweise das Auflisten und Löschen von Images, Containern und Volumes.
- Eine detaillierte Beschreibung aller wichtigen docker-Kommandos folgt in Kapitel 7, »Kommandoreferenz«.
- Selbstverständlich funktionieren alle im Folgenden beschriebenen Kommandos analog auch mit podman.
Platzbedarf von Images und Containern ermitteln Wie groß ist eigentlich der Platzbedarf für Images bzw. für den Container-Layer (also für die Daten eines Containers, die vom ursprünglichen Image abweichen)? Diese Frage beantworten die Kommandos docker images und docker ps -a -s. docker images liefert eine Liste aller heruntergeladenen bzw. selbst erzeugten Images samt Größenangabe:
docker images REPOSITO R Y TAG ... CREATED SIZE wordpres s latest 17 hours ago 550 MB mariadb latest 7 days ago 405 MB phpmyadm i n / phpmyadmi n latest 2 months ago 477 MB ...
docker ps listet standardmäßig nur die laufenden Container auf.
- Die Option -a weitet die Ausgabe auf alle jemals eingerichteten Container aus. -s fügt die Spalte SIZE hinzu.
- Sie gibt an, wie viel Platz die gegenüber dem Image geänderten Dateien beanspruchen.
- Sofern die meisten veränderlichen Daten in einem Volume ausgelagert sind, ist der zusätzliche Platzbedarf oft winzig.
- Wenn es aber Änderungen gibt, dann ist der tatsächliche Platzbedarf im lokalen Dateisystem oft spürbar größer, als docker ps vermuten lässt.
- Das liegt am Overhead des Dateisystems bei der Speicherung vieler kleiner Dateien.
Die Informationen in Klammern (virtual) beziehen sich auf die Gesamtgröße des Containers inklusive der Read-only-Images.
- Diese Daten sind insofern virtuell, als sich mehrere Container gemeinsame Images gleichsam teilen können.
docker ps -a -s
CONTAINE R ID IMAGE ... SIZE 2 bf9e954b 4 b 7 wordpress 20.1 MB ( virtual 571 MB ) 3 af937080 2 2 8 phpmyadmi n /... 70 B ( virtual 477 MB ) ac98aca3 7 f 7 a mariadb 2 B (virtual 405 MB ) ...
Container und Images löschen
docker rm <id> bzw. docker rm <name> löscht den angegebenen Container.
- Container- IDs und -Namen können Sie gegebenenfalls mit docker ps -a ermitteln.
docker rm ac98aca3 7f 7 a
Vorsicht
docker rm hat große Ähnlichkeiten mit dem klassischen rm-Kommando unter Linux: Es löscht ohne Rückfrage und ohne die Möglichkeit, die Operation rückgängig zu machen!
Das folgende Kommando erzeugt zuerst mit ps eine Liste aller IDs von Containern, die vom Image ubuntu abgeleitet sind.
- Diese Liste wird an docker rm weitergegeben, um alle Container zu löschen.
- Wenn Sie also eine Weile mit docker run ubuntu experimentiert haben, können Sie so alle bei dieser Gelegenheit erzeugten Container wieder löschen.
- Die hier präsentierte Verkettung zweier Kommandos setzt voraus, dass eine Shell wie bash oder zsh verwendet wird, wie dies unter Linux oder macOS standardmäßig der Fall ist.
- Unter Windows funktioniert das Kommando ebenfalls, sofern Sie die PowerShell verwenden.
docker rm $ ( docker ps -a -q -f ancestor = ubuntu )
Noch radikaler ist das nächste Kommando: Es löscht alle existierenden Container!
docker rm $ ( docker ps -aq )
docker rmi imagename löscht das angegebene Image.
- Das ist nur möglich, wenn es keine von dem Image abgeleiteten Container gibt.
- Die folgenden Kommandos löschen zuerst alle hello-world-Container und dann das hello-world-Image:
docker rm $ ( docker ps -a -q -f ancestor = hello - world )
docker rmi hello - world
Beachten Sie, dass docker rmi nur lokal ausgeführt wird.
- Wenn Sie ein eigenes Image in den Docker Hub hochgeladen haben, bleibt das Image dort erhalten.
- Sie können es bei Bedarf in der Weboberfläche von https://hub.docker.com löschen.
Volumes verwalten
Volumes werden getrennt von den Containern und Images in einem eigenen Verzeichnis gespeichert, unter Linux z. B. in /var/lib/docker/volumes.
- Beim Löschen von Containern rührt Docker Volumes generell nicht an.
- Sie können aber wie folgt eine
Liste mit den Namen oder IDs aller Volumes erstellen, zu denen der dazugehörende Container nicht mehr existiert:
docker volume ls -q -f dangling = true 4 df85efbf 1 2 40 b 7 4 29 f 7 b f 55 4 e 2 e ad 5 2 b 9 0a 1 9 3 4 87 5 d 5 7 77 3 c 1 c 80 c 4 0 5 d6 4 a 6 eec95274 4 a 21 b 5 5 c7 1 b 8 e 6d c 2 8 d a8 2 2 b f 3c 8 1 4 7 ed 5 4 3 5 1d c b 8 8 c3 0 0 9 4 eb 1 b ...
Die Größe der Volumes ermitteln Sie, indem Sie das obige Ergebnis an du weiterleiten. Das funktioniert in dieser Form allerdings nur auf einem Linux-Host.
- Unter Windows und macOS werden die Docker-Dateien in einem eigenen Dateisystem innerhalb einer virtuellen Maschine gespeichert, auf die Sie von außen keinen direkten Zugriff haben.
sudo du -h --max 0 \ / var / lib / docker / volumes / $ ( docker volume ls -q -f dangling = true )
Dabei müssen Sie den Ort angeben, wo die Volumes auf Ihrem System gespeichert werden.
- Falls Sie Docker Desktop verwenden, befinden sich die Volumes in einer virtuellen Maschine.
/ var / lib / docker / volumes (Docker Engine ) .
- local / share / docker / volumes (Rootless Docker )
.
- local / share / container s / storage / volumes (Podman )
Falls Sie mit Docker Desktop arbeiten, ist eine Bestimmung der Volume-Größe per Kommando nicht ohne Weiteres möglich.
- Die Volumes befinden sich in WSL- Verzeichnissen (Windows) bzw. in einer virtuellen Maschine (macOS, Linux).
- Aber dafür reicht nun ein Klick auf den Volumes-Tab in Docker Desktop aus, um diese Informationen zu ermitteln.
Alle verwaisten Volumes können Sie bei Bedarf mit dem folgenden Kommando löschen.
- Die Rückfrage können Sie mit -f unterdrücken.
docker volume prune WARNING ! This will remove all volumes not used by at least one container .
- Are you sure you want to continue ? [ y /N ] y
Den Inhalt eines Volumes ansehen
Mitunter ist es riskant, ein Volume einfach zu löschen, wenn Sie sich nicht mehr genau erinnern können, wozu das Volume verwendet wurde.
- Vielleicht befinden sich dort doch noch Daten, die Sie später brauchen.
Wenn Sie Docker Desktop bzw. Podman Desktop installiert haben, können Sie unkompliziert in Volumes »hineinsehen«, also wie in einem Dateimanager alle Verzeichnisse des Volumes öffnen und die dort gespeicherten Dateien auflisten (siehe Abbildung 3.4).
- Den Inhalt der Dateien können Sie sich dabei leider nicht ansehen, aber Sie können einzelne Dateien in das Dateisystem Ihres Host-Computers übertragen und dann dort öffnen.
Abbildung 3.4 Blick in ein Volume in Docker Desktop
Wenn Sie ohne Docker Desktop arbeiten, gelingt der Blick in das Volume beinahe ebenso einfach: Dazu starten Sie einfach einen Container und binden das Volume dort ein.
- In der Folge können Sie interaktiv alle Verzeichnisse erforschen.
- Prinzipiell reicht für diesen Zweck ein Minimal-Image (z. B. Alpine Linux oder BusyBox).
- Mehr Komfort, gerade bei der Vervollständigung von Dateiund Verzeichnisnamen, bietet aber ein Image, das die Shell bash enthält.
- Wir haben deswegen im folgenden Beispiel mit Ubuntu gearbeitet.
docker run -it --rm -v 98 b95d8 ...:/ myvol ubuntu
root # ls / myvol
index .
- php wp - comments - post .
- php wp - includes
license .
- txt wp - config -docker .
- php wp - links - opml .
- php
readme .
- html wp - config -sample .
- php wp - load .
- php
wp - activate .
- php wp - config .php wp - login .
- php
...
root # cat / myvol /index .php
...
root # exit
Anstatt das Volume interaktiv zu erforschen, können Sie auch find anwenden.
- Dazu reicht das winzige busybox-Image aus:
docker run --rm -v 98 b95d8 ...:/ myvol busybox find / myvol
Zur Auswahl des Volumes müssen Sie seine vollständige ID (siehe docker volume ls) oder bei einem benannten Volume dessen Namen angeben.
- Die ID haben wir in den obigen Beispielen nur aus Platzgründen verkürzt.
Gesamtüberblick Einen kompakten Überblick über den Speicherbedarf aller Images, Container, Volumes und des Build Caches gibt docker system df:
docker system df TYPE TOTAL ACTIVE SIZE RECLAIMAB L E Images 18 11 10.72 GB 1.854 GB (17%) Containe r s 33 4 496 MB 495.9 MB (99%) Local Volumes 2 1 169 MB 119.8 MB (70%) Build Cache 0 0 0B 0B
Wenn Sie Docker schon lange in Betrieb haben und es entsprechend viele Images, Container und Volumes gibt, kann die Ausführung dieses Kommandos eine Weile dauern. Mit der zusätzlichen Option -v listet das Kommando sämtliche Images, Container, Volumes usw.
- einzeln auf.
Ungenutzten Speicher freigeben Statt nach Images, Containern und Volumes zu suchen und sie einzeln zu löschen, können Sie für Ihre Aufräumarbeiten docker system prune zu Hilfe nehmen.
- Dieses Kommando löscht alle gerade nicht laufenden Container sowie alle Images, die nicht von anderen Images benötigt werden (dangling images).
Noch intensiver wird der Großputz durch zusätzliche Optionen:
-a bzw. --all löscht auch Images, die nicht von Containern verwendet werden. --volumes löscht auch Volumes, die mit keinem Container verbunden sind. (Vorsicht!)
docker system prune -a --volumes
WARNING ! This will remove :
- all stopped container s - all networks not used by at least one containe r - all volumes not used by at least one containe r - all images without at least one containe r associate d to them - all build cache
Are you sure you want to continue ? [ y / N ]
docker system prune ist bequem anzuwenden, schießt aber manchmal über das Ziel hinaus.
- Sicherer ist es, in kleinen Schritten vorzugehen.
- Die beiden folgenden Kommandos ermitteln zuerst alle Volumes, die nicht mehr in Verwendung sind.
- Gegebenenfalls können Sie diese Volumes dann in einem zweiten Schritt löschen.
- Beachten Sie die Option -q im zweiten Kommando, die die Ausgabe von docker volume ls auf die IDs verkürzt.
docker volume ls -f dangling = true docker volume rm $ (docker volume ls -q -f dangling = true )
docker ps -a | grep Exit listet alle beendeten Container auf.
- Das zweite Kommando
extrahiert die erste Spalte mit den IDs aus der Liste und löscht diese Container:
docker ps -a | grep Exit docker rm $ ( docker ps -a | grep Exit | cut -d ' ' -f 1)
Vielleicht gibt es einige Container, die Sie nicht löschen möchten.
- Anstatt das obige Kommando auszuführen, eliminieren Sie dann mit grep -E -v zuerst alle Zeilen, die einen der durch | getrennten Suchbegriffe enthalten.
- Wenn Sie mit der nun angezeigten Liste einverstanden sind, dann löschen Sie mit dem zweiten Kommando diese Container.
docker ps -a | grep Exit | grep -E -v 'mysql | mariadb '
docker rm $ ( docker ps -a | grep Exit | \ grep -E -v 'mysql | mariadb ' | cut -d ' ' -f 1)
Die folgenden beiden Kommandos listen zuerst alle Images auf, die von keinem Container verwendet werden, und löschen diese dann:
docker images -f dangling = true docker rmi $ ( docker images -q -f dangling = true )