Befehl ausführen ohne verknüpfte Dienste zu starten
In diesem Schritt lernen wir, wie man einen Befehl in einem Docker-Container ausführt, der Teil einer Multi-Container-Anwendung ist, ohne die anderen verknüpften Dienste zu starten. Dies ist besonders nützlich für Datenbank-Migrationen, Setup-Skripte oder Debugging-Befehle in einem Service, ohne den gesamten Anwendungsstack hochfahren zu müssen.
Während Docker Compose das Standard-Tool für die Verwaltung von Multi-Container-Anwendungen ist und Funktionen für einmalige Befehle in bestimmten Services bietet, demonstrieren wir hier die zugrundeliegenden Docker-Konzepte. Da Docker Compose in dieser Umgebung nicht vorinstalliert ist, konzentrieren wir uns auf die Verwendung des docker run
-Befehls mit Netzwerkfunktionen.
Lassen Sie uns ein einfaches Szenario mit zwei Containern simulieren: einer Webanwendung und einer Datenbank. Wir verwenden ein generisches ubuntu
-Image für unsere Webanwendung und ein postgres
-Image für die Datenbank.
Zuerst pullen wir das postgres
-Image:
docker pull postgres:latest
Sie sollten eine Ausgabe sehen, die anzeigt, dass das Image heruntergeladen wird.
Using default tag: latest
latest: Pulling from library/postgres
...
Status: Downloaded newer image for postgres:latest
docker.io/library/postgres:latest
Nun erstellen wir ein Docker-Netzwerk, damit unsere Container über Namen miteinander kommunizieren können.
docker network create my-app-network
Sie sollten die Netzwerk-ID ausgegeben sehen.
<network_id>
Als nächstes starten wir den postgres
-Container und verbinden ihn mit unserem Netzwerk. Wir setzen auch ein Passwort für den PostgreSQL-Benutzer.
docker run -d --network my-app-network --name my-database -e POSTGRES_PASSWORD=mypassword postgres
Sie sollten die Container-ID sehen, was anzeigt, dass der Datenbank-Container im Hintergrund läuft.
<container_id>
Stellen Sie sich nun vor, unser "Webanwendungs"-Container muss einen Befehl ausführen, der mit der Datenbank interagiert, wie z.B. ein Datenbank-Migrationsskript. Normalerweise, wenn wir Docker Compose verwenden würden, könnten wir einen Befehl auf dem Web-Service ausführen und Docker Compose würde die Netzwerkeinrichtung und Verknüpfung übernehmen.
Mit nur docker run
, wenn wir den Webanwendungs-Container starten würden und er versucht, eine Verbindung zu my-database
herzustellen, müsste er sich typischerweise im selben Netzwerk befinden.
Lassen Sie uns einen Befehl in einem ubuntu
-Container ausführen, der mit demselben Netzwerk verbunden ist, um einen Befehl zu simulieren, der mit der Datenbank interagieren könnte. Wir versuchen einfach, den Datenbank-Container über seinen Namen (my-database
) zu pingen.
docker run --network my-app-network ubuntu ping -c 4 my-database
Dieser Befehl wird:
- Einen neuen Container aus dem
ubuntu
-Image erstellen
- Ihn mit dem
my-app-network
verbinden
- Den Befehl
ping -c 4 my-database
im Container ausführen
Da der ubuntu
-Container im selben Netzwerk wie der my-database
-Container ist, kann er den Namen my-database
in die IP-Adresse des Datenbank-Containers auflösen und ihn anpingen.
Sie sollten eine Ausgabe sehen, die die Ping-Anfragen und Antworten zeigt:
PING my-database (172.18.0.2) 56(84) bytes of data.
64 bytes from my-database.my-app-network (172.18.0.2): icmp_seq=1 ttl=64 time=0.050 ms
64 bytes from my-database.my-app-network (172.18.0.2): icmp_seq=2 ttl=64 time=0.054 ms
64 bytes from my-database.my-app-network (172.18.0.2): icmp_seq=3 ttl=64 time=0.054 ms
64 bytes from my-database.my-app-network (172.18.0.2): icmp_seq=4 ttl=64 time=0.054 ms
--- my-database ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3060ms
rtt min/avg/max/mdev = 0.050/0.053/0.054/0.001 ms
Dies zeigt, dass Sie einen einmaligen Befehl in einem Container ausführen können und dieser mit anderen Containern im selben Netzwerk interagieren kann, ohne den Standard-Service des Containers starten zu müssen (in diesem Fall hat der ubuntu
-Container keinen typischen "Service"). Der Schlüssel liegt darin, den Container, der den Befehl ausführt, mit demselben Netzwerk zu verbinden wie die Services, mit denen er interagieren muss.
Abschließend bereinigen wir den laufenden Datenbank-Container und das Netzwerk.
docker stop my-database
my-database
docker rm my-database
my-database
docker network rm my-app-network
my-app-network