MariaDB-Testserver mit Docker als Linux-Container installieren
https://oer-informatik.de/docker-install-mariadb
tl/dr; (ca. 20 min Lesezeit): Mit MariaDB lassen sich besonders leicht Container aufsetzen und mit Daten befüllen. In diesem Tutorial werden Voraussetzungen für den Container zusammengetragen, die nötigen Befehle zusammengestellt. Am Ende können wir individuelle versionierbare Datenbanken auf Knopfdurck zur Verfügung stellen. Oder, um es zu buzzworden: “Infrastructure as Code”.
Voraussetzungen
Hilfreich (aber nicht zwingend) für dieses Tutorial sind Grundkenntnisse im Umgang mit Docker. Wir benötigen ein Terminal nach Wahl (Powershell, Bash…), eine lauffähige Docker-Umgebung. Ich gebe die Befehle, die auf dem Host-System ausgeführt werden immer in Powershell-Notation an (mit führendem PS>
), die Befehle, die im Container abgesetzt werden, mit CT:/$
. Ich hoffe, dass erleichtert die Zuordnung auch bei allen, die (sinnvollerweise) in beiden Fällen Linux nutzen.
Ein aktuelles Docker Image für MariaDB vom Docker Hub laden
Das Image wird durch folgenden Befehl geladen und als Dienst im Hintergrund gestartet. Individuell gewählt werden kann der Name (hier: mariadb1
), das Name und Initialpasswort des Datenbanknutzers (hier dbuser
/ _hier%1GutesPWnu+2en
) und des Datenbank-Root-Nutzers sowie die Port-Weiterleitung (hier auf den lokalen Port 3307
):
Docker antwortet mit einem relativ langen Hashwert, etwa: > ffd2c884d1500eaba29456da0e21be22630a836328f337e7f510a995b425ba0c
Die Optionen im einzelnen:
Option | Bedeutung |
---|---|
--name XYZ |
setzt den Containernamen auf XYZ (individualisierbar); sinnvoll ist Zahl am Ende des Containernamens, um mehrere Container des gleichen Images unterschieden zu können |
-d |
detach: der Container wird im Hintergrund weiter ausgeführt, der MySQL-Server bleibt erreichbar |
-p 3307:3306 |
Port 3306 des Containers wird auf den Port 3307 des hosts gemappt.1 |
-e MARIADB_USER=dbuser |
setzt eine (leicht auslesbare) Umgebungsvariable für den Nutzernamen des späteren Datenbanknutzers |
-e MARIADB_PASSWORD=_hier%1GutesPWnu+2en |
setzt eine (leicht auslesbare) Umgebungsvariable für das Datenbankpasswort des oben eingerichteten Nutzers. Sicherheitsrisiko: muss später unbedingt geändert werden! |
MARIADB_ROOT_PASSWORD=_hier%1auchGutesPWnu+2en |
setzt eine (leicht auslesbare) Umgebungsvariable für das Datenbank-root-Passwort. Sicherheitsrisiko: muss später unbedingt geändert werden! |
-e MYSQL_ROOT_HOST=% |
Umgebungsvariable von MySQL für den Host, der als root zugreifen darf; % bedeutet: alle |
mariadb:latest |
nutzt das neuste MariaDB-Image; es können auch konkrete Versionen per tag übergeben werden, z.B. statt latest auch 10.9-jammy . Eine Liste der angebotenen Tags findet sich hier |
Im UML-Sequenzdiagramm sieht der Ablauf etwa wie folgt aus (natürlich weicht der Docker-Befehl in diesem Beispiel ab, da MS SQL-Server hier geladen wird):

Der Rückgabewert (in meinem Fall ffd2c...
) ist ein Hashwert, über den der Container identifizierbar ist.
Es wird eine Containerinstanz erzeugt, die im Hintergrund läuft (über die Option -d wird der Container als detached ausgeführt).
Analog kann auch ein Container für MySQL gestartet werden. Im Gegensatz zu MariaDB ist MySQL jedoch nicht als OpenSource veröffentlicht, nutzt aber weitgehend die gleichen Funktionalitäten:
PS> docker run --name=mysql1 -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=_hier%1GutesPWnu+2en -e MYSQL_ROOT_HOST=% mysql/mysql-server:latest`)
Die Logs auslesen
Falls etwas mal nicht klappt ist es sehr hilfreich, in den Logs nach Fehlern zu suchen. Wenn die Passwörter z.B. nicht per -e
Option übergeben wurden werden diese auch in den Logs gespeichert.
Die kompletten ungefilterten Logs finden sich mit dem Befehl:
Es ist jedoch häufig schwierig, in der Fülle der Zeilen die relevante Information zu finden. Sollte z.B. ein generietes Passwort aus den Logs herausgesucht werden, so helfen die Filtermethoden der Powershell und Bash, um das Log auf die relevanten Zeilen einzugrenzen:
Windows/Powershell:
Linux, *nix/Shell:
sh:/$ docker logs mariadb1 2>&1 | grep GENERATED
Die SQL-Kommandozeile öffnen
Manchmal will man nicht extra ein Frontend öffnen, um schnell einen SQL-Befehl abzusetzen. Um im Container mariadb1
mit dem Benutzer root
eine SQL-Shell zu erhalten, muss der folgende Befehl eingegeben werden:
docker exec -it mariadb1 mariadb -uroot -p
Nach Eingabe des zugehörigen Passworts ist die SQL-Konsole bereit:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 20
Server version: 10.9.3-MariaDB-1:10.9.3+maria~ubu2204 mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
Daraufhin lassen sich SQL-Befehle (mit abschließendem Semicolon) absetzen:
+---------------------------------------+
| VERSION() |
+---------------------------------------+
| 10.9.3-MariaDB-1:10.9.3+maria~ubu2204 |
+---------------------------------------+
1 row in set (0.000 sec)
Die vergebenen Passwörter ändern
So lässt sich beispielsweise auch das Passwort ändern, um dem Sicherheitsrisiko, dass es über Umgebungsvariable und Befehlshistory auslesbar ist zu entgehen:
Query OK, 0 rows affected (0.007 sec)
Die SQL-Konsole lässt sich mit exit
beenden
> Bye
Das geht natürlich auch alles über ein Frontend. Und dazu kommen iwr jetzt.
Zugriff per Frontend (am Beispiel DBeaver)
Komfortabler ist natürlich die Bedienung per Frontend. Die oben gewählten Benutzerdaten und Ports müssen in die Anmeldemaske des DB-Frontends eingetragen werden. Der Ablauf ist immer der selbe und wird hier einmal exemplarisch mit dem Frontend DBeaver umgesetzt.
Das Frontend DBeaver tut sich manchmal ein bisschen schwer wenn es darum geht, die korrekte Java-JVM zu finden. Bei mir hat geholfen, in der Datei dbeaver.ini
direkt im Programmverzeichnis (Windows: C:\Program Files\DBeaver
) folgende Zeilen einzufügen. Wichtig: -vm
muss in einer gesonderten Zeile stehen, der Pfad zur aktuellen jvm.dll
in der darauf folgenden Zeile.
Anpassungen in der `dbeaver.ini
-vm
C:\Program Files\Java\jdk-17.0.4\bin\server\jvm.dll
Wenn DBeaver startet muss zunächst eine “Neue Verbindung” zum Container eingerichtet werden:

Dann muss der richtige Treiber für das jeweilige DBMS ausgewählt werden (ggf. startet dann ein Download):

Danach müssen die Benutzerdaten und der Port eingegeben werden. Der oben eingerichtete User root
hat dabei Zugriff auf alle Datenbanken und Tabellen, der dbuser
sieht zunächst eine leere Datenbank und muss dann selbst tätig werden.

Wenn alles geklappt hat findet sich links in der Spalte die Datenbanknavigation, in der später alle Datenbanken auswählbar sind, im großen Fenster lässt sich über das Menü (gelb) ein SQL-Script öffnen. In das Fenster können dann die eigentlichen SQL-Befehle eingegeben werden (hier als Beispiel: SELECT VERSION()
in blau). Ausgeführt werden die Befehle dann mit dem “Play”-Symbol (grün), woraufhin in der unteren Hälfte das Ergebnis der Abfrage erscheint.

MariaDB in Docker-Container automatisch mit Daten füllen
Oft ist es hilfreich, wenn man unmittelbar bei Container-Erstellung ein File mit SQL-Befehlen ausführen kann - beispielsweise um direkt eine Testdatenbank verfügbar zu haben. Im einfachsten Fall kann das erreicht werden, in dem man ein Verzeichnis des Hostsystems innerhalb des Containers als “Volume” mountet (es also im Container unter einem definierten Pfad einbindet). Wenn dieses Volume unter /docker-entrypoint-initdb.d
eingebunden wird und eine SQL-Datei enthält, so wird diese dann direkt in der DB ausgeführt. Aber vorsicht: auch alle *.sh
-Dateien werden direkt ausgeführt.
Die Option, um die unser Befehl oben ergänzt werden muss lautet:
-v /lokaler/Pfad/zur/SQLOrdner:/docker-entrypoint-initdb.d
Am einfachsten ist es, sich direkt in dem Verzeichnis zu befinden, dass eingefügt werden soll. Dann kann das aktuelle Workingdirectory direkt mit dem PWD
-Befehl (“Print working directory”) eingebunden werden. Die Syntax ist in der Powershell etwas anders als in der Bash:
Linux oder *nix/Bash
-v $(pwd):/docker-entrypoint-initdb.d
Windows/Powershell:
Wenn also beispielsweise eine Datei setup.sql
im aktuellen Verzeichnis liegt, könnte auf einem Windows-Rechner in der Powershell der Container gestartet werden mit:
docker run --rm --name=mariadb1 -d -p 3307:3306 -e MARIADB_USER=dbuser -e MARIADB_PASSWORD=_hier%1GutesPWnu+2en -e MARIADB_ROOT_PASSWORD=_hier%1auchGutesPWnu+2en -v ${PWD}:/docker-entrypoint-initdb.d mariadb:latest
Eine einfache Beispieldatei zum Import findet sich hier
Zum Schluss: Container-Admin in 20s: ausschalten, wieder einschalten oder löschen
Irgendwann ist Feierabend und auch der Container soll schlafen. Wie das bei Containern grundsätzlich geht habe ich hier zusammengefasst, im Schnelldurchgang seien hier aber die wichtigsten Befehle nochmals genannt:
Welche Container wurden erzeugt, welche laufen und wie viel Speicher benötigen sie?
Welche Images wurden geladen und wie viel Speicher verwenden sie?
Einen laufenden Container ausschalten, um ihn später wieder zu nutzen (hier: Name mariadb1
, ginge auch per Hash/ID:
Einen gestoppten Container wieder aktivieren, um ihn am nächsten Tag weiter zu nutzen (hier: Name mariadb1
, ginge auch per Hash/ID):
Einen Container, den man nicht mehr benötigt, löschen (hier: Name mariadb1
, ginge auch per Hash/ID)
Ein Image, das man nicht mehr benötigt, löschen (hier: Name mariadb:latest
)
Fazit
Mit MariaDB lassen sich deutlich schlankere Container deutlich einfacher erstellen als mit MS-SQL. Am Ende hatten wir nur einen Einzeiler, der direkt eine befüllte Datenbank erzeugt hat. Mit etwas Übung lassen sich so Testumgebungen schnell aufsetzen oder Übungsinstanzen erstellen.
Links und weitere Informationen
Quellen und offene Ressourcen (OER)
Die Ursprungstexte (als Markdown), Grafiken und zugrunde liegende Diagrammquelltexte finden sich (soweit möglich in weiterbearbeitbarer Form) in folgendem git-Repository:
https://gitlab.com/oer-informatik/db-sql/dbms.
Sofern nicht explizit anderweitig angegeben sind sie zur Nutzung als Open Education Resource (OER) unter Namensnennung (H. Stein, oer-informatik.de) freigegeben gemäß der Creative Commons Namensnennung 4.0 International Lizenz (CC BY 4.0).
ich mappe die Ports unterschiedlicher DBMS auf die lokalen Ports 3307-3312, da diese durch kein lokales DBMS belegt sind, aber direkt hinter dem MySQL-Standardport 3306 folgen. Jeder andere freie Port ist ebenso möglich, muss nur bei der DB-Verbindung anpasst werden.↩