Ich erinnere mich noch gut an die Zeiten, als die Bereitstellung und Verwaltung von Softwareanwendungen eine komplexe Herausforderung war mit variablen Umgebungen und unvorhersehbaren Fehlern. Dann stieß ich auf Docker, ein Werkzeug, das versprach, viele dieser Probleme durch die sogenannte Containerisierung zu lösen. Aber was genau ist Docker? Und warum hat es sich als so revolutionär für die IT erwiesen?
Docker erlaubt es, Anwendungen zusammen mit ihren Abhängigkeiten in einem isolierten Container zu verpacken. Dies bedeutet eine hohe Wahrscheinlichkeit, dass meine Software überall gleich läuft, egal auf welcher Plattform sie ausgeführt wird. Dieser Beitrag soll eine einfache und verständliche Einführung in die Grundlagen von Docker geben. Was sind Docker-Container, wie funktionieren sie anhand einfacher Beispiele.
Installation
Für Docker gibt es entsprechende Softwarepakete die eine Installation unter Windows, macOS und Linux unterstützen. Im Internet gibt es dazu zahlreiche Anleitungen, sodass ich in diesem Beitrag auf eine genaue Erläuterung der Installation verzichte. Unter Linux ist die Abhängigkeit von Docker mit den Besonderheiten der jeweiligen Linuxdistribution nicht immer trivial. So unterscheidet sich die Installation unter Ubuntu deutlich von der unter RHEL/Fedora oder Raspberry Pi OS. Um diesen Beitrag zu folgen, gehe ich erst einmal davon aus, das Docker erfolgreich auf einem Linux-System installiert ist und setze Erfahrung im Umgang mit dem Terminal/Kommandozeile voraus.
Docker ausprobieren, ohne Installation
Um Docker auszuprobieren und erste Erfahrungen zu sammeln, ohne es auf dem eigenen System zu installieren, bieten sich vor allem online mehrere Möglichkeiten:
- Play with Docker (PWD): Play with Docker ist eine kostenlose, von Docker bereitgestellte Online-Umgebung, in der Docker direkt im Webbrowser ausprobiert werden kann
- Kataconda: eine interaktive Lernplattform in der man eine Docker-Umgebung direkt im Browser nutzen kann ohne irgendwelche Installationen durchführen zu müssen.
- Google Cloud Shell: Mittels Webbrowser bietet die Google Cloud Shell eine Zugriff auf eine vorkonfigurierte Entwicklungsumgebung mit vorinstallierten Docker. Ähnliche Möglichkeiten gibt es von der Microsoft Azure Cloud-Shell sowie von AWS Cloud9.
Erste Gehversuche mit Docker
Um herauszufinden, welche Version von Docker auf dem System installiert ist, gibt man im Terminal (z. B. Google Cloud Shell) folgenden Befehl ein:
docker --version
Dieser Befehl gibt die Version von Docker aus, zusammen mit einigen zusätzlichen Informationen zur Build-Version und zum Veröffentlichungsdatum. Wenn man detailliertere Informationen über die Installation erhalten möchten, ist folgender Befehl hilfreich:
docker version
Das Ergebnis zeigt mehr Details, einschließlich der Versionen von sowohl dem Docker-Client als auch dem Docker-Server (Docker Daemon), was nützlich sein kann, um Kompatibilitätsprobleme zu diagnostizieren.
docker ps -a
liefert eine Übersicht aller (-a = all) laufenden bzw. in der Vergangenheit ausgeführten Docker-Container, während docker ps (ohne -a) nur die aktuell laufenden Container anzeigt. Docker ps -l zeigt den letzten erstellten Container an.
docker images
gibt eine Liste der lokal installierten Images sowie den jeweils benötigten Speicherbedarf aus,
docker rmi imagename
löscht das angegebene Image.
Einen ersten Container erstellen
Um eine Docker-Container zu starten, verwendet man den Befehl docker run. Dieser Befehl erzeugt und startet einen Container aus einem Docker-Image. Die grundlegende Syntax für diesen Befehl im Terminal unter Linux sieht wie folgt aus:
docker run [Optionen] [Image]
Ein einfaches erstes Beispiel für einen Docker-Container wäre:
docker run hello-world
Das Kommando prüft zuerst, ob das Image für den hello-world Container auf dem System bereits zur Verfügung steht. Sollte das nicht der Fall sein, wird der Container von Docker Hub heruntergeladen, gespeichert und anschließend sofort ausgeführt.
Hier sind einige der wichtigsten Optionen, die man mit docker run verwenden kann:
- -d: Startet den Container im Hintergrund (detached mode)
- – -name: Weist dem Container einen Namen zu
- -p: Leitet einen öffentlichen Port auf einen privaten Port im Container weiter (z. B.: -p 80:80)
- -e: Setzt Umgebungsvariablen oder Passwörter (z. B. -e MY_VAR=my_value)
- -v: Bindet einem Volume vom Host-System an den Container
- -i oder –interactive: Der Container wird interaktiv ausgeführt
- -t oder –tty: Weist Docker an., ein pseudo-TTY (ein virtuelles Terminal) zuzuweisen.
- – -rm: remove – der Container wird gelöscht, sobald die Ausführung endet
- -h: hostname – legt den Host-Namen für den Container fest
Die letzten beiden Optionen werden in der Regel als Kombination -it verwendet, wenn der Container in einem Terminal- oder PowerShell-Fenster interaktiv genutzt werden soll.
Mit dem folgenden Befehl wird das aktuell Ubuntu Linux-Image heruntergeladen, ein darauf basierender Container erzeugt und ausgeführt. Man landet dabei in der Bash-Shell des Containers.
docker run -it --name my_ubuntu ubuntu bash
Mit dem Linuxbefehl cat /etc/os-release kann man sehr einfach überprüfen, welches Betriebssystem (in diesem Fall Ubuntu) im Container läuft.
Mit exit oder [STRG] + [D] kann man den Container wieder verlassen und gelangt in das Terminal des Host-Systems.
Vorhandene Container erneut ausführen
Im vorherigen Beispiel wird der Ubuntu-Container nach dem Verlassen auch sofort beendet. Mittels docker ps -a sieht man in der Spalte „STATUS“ auf einen Blick, dass der Container my_ubuntu vor kurzem beendet wurde (Exited (0) 51 seconds ago).
Um den selben Container zu einem späteren Zeitpunkt wieder zu verwenden, wird der Befehl docker start [Container-Name] verwendet.
docker start -ia my_ubuntu
Damit der Container wieder interaktiv verwendet werden kann, muss die Option -i vorangestellt werden. Die Option -t ist in diesem Fall nicht zulässig da die meisten Optionen beim erzeugen eines Container mit docker run dauerhaft gespeichert werden. -i ist hier jedoch eine Ausnahme. Die Option -a kommt aus dem Bereich, wenn man Podman verwendet und schadet nicht im Zusammenhang mit docker start, was letztendlich zu docker start -ia [Container-Name] führt.
Container mit lokalen Ports verbinden
Möchte man eine Webserver in einem Container betreiben, ist es sinnvoll, den HTTP-Port des Container mit dem lokalen Netzwerk das Host-Systems zu verknüpfen, damit die bereitgestellten Seiten des Webservers auch erreichbar sind.
Mit der Option -p, kann Port 80 des Containers mit einem freien Port des Host-Rechners verknüpft werden. Port 80 ist der übliche Port für das HTTP-Protokoll. Dabei ist die Syntax oder Reihenfolge der Ports zu beachten: -p [hostport]:[containerport]
docker run -d -p 80:80 --name webserver docker/getting-started
- -d – Container wird im Detached-Mode ausgeführt (läuft im Hintergrund)
- -p 80:80 – mapped Port 80 des Host-Systems auf Port 80 des Docker-Containers
- –name webserver – vergebener Name an den Docker-Container
- docker/getting-started – Name des Docker-Image
Ist der Port 80 auf dem Host-Rechner noch frei – es läuft kein weiterer Service auf diesem Port, ist die Webseite unter http://localhost bzw. http://localhost:80 zu erreichen.
In Entwicklungsumgebungen ist oftmals Port 80 bereits durch einen anderen Dienst belegt. Diesen Umstand kann man sehr leicht begegnen, in dem man die Optionen von docker run ein wenig verändert und einen anderen Zielport z. B. Port 8080 angibt.
docker run -d -p 8080:80 --name webserver_new docker/getting-started
Container stoppen
Nicht mehr benötigte Container können sehr einfach mit docker stop [Containername] gestoppt werden. An den Stop-Befehl können auch mehrere Container-Namen auf einmal übergeben werden. Diese Prinzip funktioniert auch für docker start.
docker stop webserver_new my_ubuntu