So installieren und verwenden Sie Docker Compose auf Ubuntu
Einführung
Docker vereinfacht den Prozess der Verwaltung von Anwendungsprozessen in Containern. Obwohl Container in gewisser Weise virtuellen Maschinen ähneln, sind sie leichter und ressourcenschonender. Dies ermöglicht es Entwicklern, eine Anwendungsumgebung in mehrere isolierte Dienste aufzuteilen.
Für Anwendungen, die von mehreren Diensten abhängen, kann es schnell unübersichtlich werden, alle Container zu orchestrieren, damit sie gemeinsam starten, kommunizieren und heruntergefahren werden. Docker Compose ist ein Werkzeug, das es ermöglicht, Multi-Container-Anwendungsumgebungen basierend auf Definitionen in einer YAML-Datei auszuführen. Es verwendet Dienstdefinitionen, um vollständig anpassbare Umgebungen mit mehreren Containern zu erstellen, die Netzwerke und Datenvolumen teilen können.
Dieser Leitfaden zeigt Ihnen, wie Sie Docker Compose auf einem Ubuntu-Server installieren und einen einfachen Container ausführen. Danach lernen Sie, eine Multi-Service-Umgebung mit einer WordPress-Anwendung und einer MySQL-Datenbank zu erstellen. Wir behandeln auch fortgeschrittene Themen, einschließlich der Skalierung von Services, der Definition benutzerdefinierter Netzwerke und der Verwendung modularer Include-Direktiven. Schließlich bietet dieser Artikel eine Migrationsanleitung von dem älteren docker-compose (v1) zur modernen docker compose (v2) sowie einen ausführlichen Abschnitt zur Fehlerbehebung bei häufigen Problemen wie Portkonflikten und Berechtigungsfehlern.
Wichtige Erkenntnisse:
- Docker Compose ist ein Tool zum Definieren und Ausführen von Multi-Container-Anwendungen, bei dem eine einzige YAML-Datei verwendet wird, um Dienste, Netzwerke und Volumes zu konfigurieren.
- Docker Compose wird auf Ubuntu installiert, indem das offizielle Repository von Docker hinzugefügt und
aptverwendet wird, um das Paketdocker-compose-pluginzu installieren. - Der moderne Befehl ist
docker compose(mit einem Leerzeichen). Dies ersetzt das veraltete Tooldocker-compose(mit einem Bindestrich) der Version 1. - Verwenden Sie
docker compose up -d, um eine Anwendung im Hintergrund zu starten, unddocker compose down, um alle ihre Container und Netzwerke zu stoppen und zu entfernen. - Die
depends_on-Direktive hilft dabei, die Startreihenfolge von Diensten zu steuern, zum Beispiel sicherzustellen, dass ein Datenbank-Container vor einem Webanwendungs-Container gestartet wird. - Die häufigsten Probleme sind „Permission Denied“ (gelöst, indem man seinen Benutzer zur
docker-Gruppe hinzufügt), Portkonflikte (gelöst durch Ändern des Host-Ports in der YAML-Datei) und YAML-Syntaxfehler (gelöst durch Korrigieren der Einrückung). - Sie können mehrere Instanzen eines Dienstes mit dem Befehl
docker compose up --scale <service_name>=<number>ausführen. - Die
include-Direktive ermöglicht es Ihnen, eine großedocker-compose.yml-Datei in kleinere, besser handhabbare Konfigurationsdateien aufzuteilen.
Voraussetzungen
Um diesem Artikel zu folgen, benötigen Sie:
- Zugang zu einer lokalen Ubuntu-Maschine oder einem Entwicklungsserver als Nicht-Root-Benutzer mit Sudo-Rechten. Wenn Sie einen Remote-Server verwenden, wird empfohlen, eine aktive Firewall zu installieren. Um diese einzurichten, lesen Sie bitte unseren Leitfaden zur Ersteinrichtung eines Ubuntu-Servers.
- Docker auf Ihrem Server oder lokalen Rechner installiert, gemäß Schritten 1 und 2 von „Wie man Docker auf Ubuntu installiert – Schritt-für-Schritt-Anleitung“.
Hinweis: Ab Docker Compose v2 hat Docker den Übergang zur Verwendung des compose CLI-Plugin-Befehls vollzogen und entfernt sich vom ursprünglichen docker-compose, wie in unserer Anleitung How to Install Docker Compose on Ubuntu (Step-by-Step Guide) dokumentiert. Während sich die Installation unterscheidet, besteht die eigentliche Nutzung im Allgemeinen darin, den Bindestrich aus docker-compose-Aufrufen zu entfernen, sodass docker compose verwendet wird. Für vollständige Kompatibilitätsdetails konsultieren Sie bitte die offizielle Docker-Dokumentation zur Befehlskompatibilität zwischen dem neuen compose und dem alten docker-compose.
Schritt 1 — Installation von Docker Compose
Es gibt zwei Möglichkeiten, Docker Compose auf Ubuntu zu installieren:
- Über das Repository installieren
- Manuell installieren
Wir werden in diesem Abschnitt beide Möglichkeiten besprechen.
Installation von Docker Compose über das apt-Repository
Zuerst richten wir das Docker-apt-Repository ein.
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get updateJetzt können Sie Docker Compose mit folgendem Befehl installieren:
sudo apt install docker-compose-pluginDocker Compose ist nun erfolgreich auf Ihrem System installiert. Um zu überprüfen, ob die Installation erfolgreich war, können Sie Folgendes ausführen:
docker compose versionDu wirst eine ähnliche Ausgabe wie diese sehen:
Docker Compose version v2.3.3Docker Compose manuell installieren
Um sicherzustellen, dass Sie die aktuellste stabile Version von Docker Compose erhalten, laden Sie diese Software von ihrem offiziellen Github-Repository herunter.
Überprüfen Sie zunächst die neueste verfügbare Version auf ihrer Release-Seite. Zum Zeitpunkt des Schreibens ist die aktuellste stabile Version v2.40.2.
Verwenden Sie den folgenden Befehl, um herunterzuladen:
mkdir -p ~/.docker/cli-plugins/
curl -SL https://github.com/docker/compose/releases/download/v2.40.2/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-composeAls Nächstes setzen Sie die richtigen Berechtigungen, damit der Befehl docker compose ausführbar ist:
chmod +x ~/.docker/cli-plugins/docker-composeIm nächsten Abschnitt sehen Sie, wie Sie eine docker-compose.yml-Datei einrichten und mit diesem Tool eine containerisierte Umgebung starten und betreiben.
Schritt 2 — Einrichten einer docker-compose.yml-Datei
Um zu demonstrieren, wie man eine docker-compose.yml-Datei einrichtet und mit Docker Compose arbeitet, erstellen Sie eine Webserver-Umgebung mithilfe des offiziellen Nginx-Images von Docker Hub, dem öffentlichen Docker-Registry. Diese containerisierte Umgebung wird eine einzelne statische HTML-Datei bereitstellen.
Beginnen Sie damit, ein neues Verzeichnis in Ihrem Heimatordner zu erstellen, und wechseln Sie dann dorthin:
mkdir ~/compose-demo
cd ~/compose-demoRichten Sie in diesem Verzeichnis einen Anwendungsordner ein, der als Dokumentstamm für Ihre Nginx-Umgebung dient:
mkdir appErstellen Sie mit Ihrem bevorzugten Texteditor eine neue index.html-Datei im app-Ordner:
nano app/index.htmlFügen Sie den folgenden Inhalt in diese Datei ein:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Docker Compose Demo</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/kognise/water.css@latest/dist/dark.min.css">
</head>
<body>
<h1>This is a Docker Compose Demo Page.</h1>
<p>This content is being served by an Nginx container.</p>
</body>
</html>Speichern Sie die Datei und schließen Sie sie, wenn Sie fertig sind. Wenn Sie nano verwenden, können Sie das tun, indem Sie CTRL+X, dann Y und ENTER eingeben, um zu bestätigen.
Erstellen Sie als Nächstes die Datei docker-compose.yml:
nano docker-compose.yml
Fügen Sie den folgenden Inhalt in Ihre docker-compose.yml-Datei ein:
services:
web:
image: nginx:alpine
ports:
- "8000:80"
volumes:
- ./app:/usr/share/nginx/htmlIn modernem Docker Compose ist das version-Feld optional und wird oft weggelassen, da Compose die Konfigurationsversion automatisch erkennen kann. Das obige Beispiel enthält kein version-Feld, was für die meisten neuen Projekte der empfohlene Ansatz ist. Sie müssen version nur für die Kompatibilität mit älteren Versionen angeben.
Dann haben Sie den services-Block, in dem Sie die Dienste einrichten, die zu dieser Umgebung gehören. In Ihrem Fall haben Sie einen einzelnen Dienst namens web. Dieser Dienst verwendet das nginx:alpine-Image und richtet eine Portweiterleitung mit der ports-Anweisung ein. Alle Anfragen auf Port 8000 der Host-Maschine (dem System, von dem aus Sie Docker Compose ausführen) werden an den web-Container auf Port 80 weitergeleitet, wo Nginx läuft.
Die volumes-Direktive erstellt ein gemeinsames Volume zwischen dem Host-Rechner und dem Container. Dadurch wird der lokale app-Ordner mit dem Container geteilt, und das Volume befindet sich im Container unter /usr/share/nginx/html, wodurch das standardmäßige Document Root von Nginx überschrieben wird.
Speichern und schließen Sie die Datei.
Sie haben eine Demoseite und eine docker-compose.yml-Datei eingerichtet, um eine containerisierte Webserver-Umgebung zu erstellen, die diese bereitstellt. Im nächsten Schritt werden Sie diese Umgebung mit Docker Compose starten.
Schritt 3 — Ausführen von Docker Compose
Mit der vorhandenen docker-compose.yml-Datei können Sie nun Docker Compose ausführen, um Ihre Umgebung zu starten. Der folgende Befehl lädt die erforderlichen Docker-Images herunter, erstellt einen Container für den web-Dienst und führt die containerisierte Umgebung im Hintergrundmodus aus:
docker compose up -dDocker Compose sucht zunächst nach dem definierten Image auf Ihrem lokalen System, und wenn es das Image nicht finden kann, wird es das Image von Docker Hub herunterladen. Sie werden eine Ausgabe wie diese sehen:
Creating network "compose-demo_default" with the default driver
Pulling web (nginx:alpine)...
alpine: Pulling from library/nginx
cbdbe7a5bc2a: Pull complete
10c113fb0c77: Pull complete
9ba64393807b: Pull complete
c829a9c40ab2: Pull complete
61d685417b2f: Pull complete
Digest: sha256:57254039c6313fe8c53f1acbf15657ec9616a813397b74b063e32443427c5502
Status: Downloaded newer image for nginx:alpine
Creating compose-demo_web_1 ... doneHinweis: Wenn Sie beim Ausführen von docker compose up auf einen „Permission denied“-Fehler stoßen, bedeutet dies in der Regel, dass Ihr Benutzer ohne Root-Rechte keine Berechtigung hat, auf den Socket des Docker-Daemons zuzugreifen.
Standardmäßig bindet sich der Docker-Daemon an einen Unix-Socket (/var/run/docker.sock), der dem root-Benutzer gehört. Um dies zu beheben, müssen Sie Ihren Nicht-Root-Benutzer zur docker-Gruppe hinzufügen, die während der Docker-Installation erstellt wird.
Führen Sie den folgenden Befehl aus, um Ihren Benutzer zur docker-Gruppe hinzuzufügen:
sudo usermod -aG docker ${USER}Nachdem Sie diesen Befehl ausgeführt haben, müssen Sie sich ab- und wieder anmelden, damit die Gruppenänderungen wirksam werden. Sie können die Änderungen auch für die aktuelle Terminal-Sitzung aktivieren, indem Sie Folgendes eingeben:
newgrp dockerDieser Befehl sollte alle Berechtigungsfehler im Zusammenhang mit dem Docker-Socket beheben. Für eine vollständige Anleitung lesen Sie bitte Schritt 2 von Wie man Docker auf Ubuntu installiert – Schritt-für-Schritt-Anleitung.
Ihre Umgebung läuft jetzt im Hintergrund. Um zu überprüfen, dass der Container aktiv ist, können Sie Folgendes ausführen:
docker compose psDieser Befehl zeigt Ihnen Informationen über die laufenden Container und deren Zustand sowie alle derzeit eingerichteten Port-Weiterleitungen an:
Name Command State Ports
----------------------------------------------------------------------------------
compose-demo_web_1 /docker-entrypoint.sh ngin ... Up 0.0.0.0:8000->80/tcpSie können nun auf die Demo-Anwendung zugreifen, indem Sie Ihren Browser entweder auf localhost:8000 richten, wenn Sie diese Demo auf Ihrem lokalen Rechner ausführen, oder auf Ihre_Server_Domain_oder_IP:8000, wenn Sie diese Demo auf einem entfernten Server ausführen.
Du wirst eine Seite wie diese sehen:
Das in der docker-compose.yml-Datei eingerichtete gemeinsame Volume hält die Dateien Ihres app-Ordners mit dem Dokumentenstamm des Containers synchron. Wenn Sie Änderungen an der index.html-Datei vornehmen, werden diese automatisch vom Container übernommen und somit beim Neuladen der Seite in Ihrem Browser angezeigt.
Im nächsten Schritt sehen Sie, wie Sie Ihre containerisierte Umgebung mit Docker-Compose-Befehlen verwalten.
Schritt 4 — Vertraut werden mit Docker-Compose-Befehlen
Sie haben gesehen, wie man eine docker-compose.yml-Datei einrichtet und die Umgebung mit docker compose up startet. Sie werden nun sehen, wie man Docker Compose-Befehle verwendet, um Ihre containerisierte Umgebung zu verwalten und mit ihr zu interagieren.
Um die von Ihrem Nginx-Container erzeugten Protokolle zu überprüfen, können Sie den Befehl logs verwenden:
docker compose logsDu wirst eine ähnliche Ausgabe sehen:
Attaching to compose-demo_web_1
web_1 | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
web_1 | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
web_1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
web_1 | 10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
web_1 | 10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
web_1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
web_1 | /docker-entrypoint.sh: Configuration complete; ready for start up
web_1 | 172.22.0.1 - - [02/Jun/2020:10:47:13 +0000] "GET / HTTP/1.1" 200 353 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36" "-"Wenn Sie die Ausführung der Umgebung pausieren möchten, ohne den aktuellen Zustand Ihrer Container zu ändern, können Sie Folgendes verwenden:
docker compose pausePausing compose-demo_web_1 ... doneUm die Ausführung nach dem Einlegen einer Pause fortzusetzen:
docker compose unpauseUnpausing compose-demo_web_1 ... doneDer stop-Befehl beendet die Ausführung des Containers, zerstört jedoch keine Daten, die mit Ihren Containern verbunden sind:
docker compose stopStopping compose-demo_web_1 ... doneWenn Sie die mit dieser containerisierten Umgebung verbundenen Container, Netzwerke und Volumes entfernen möchten, verwenden Sie den Befehl down:
docker compose downRemoving compose-demo_web_1 ... done
Removing network compose-demo_defaultBeachten Sie, dass dies das Basis-Image, das Docker Compose zum Starten Ihrer Umgebung verwendet (in Ihrem Fall nginx:alpine), nicht entfernt. Auf diese Weise wird der Prozess beim nächsten Start Ihrer Umgebung mit docker compose up viel schneller sein, da das Image bereits auf Ihrem System vorhanden ist.
Falls Sie auch das Basisbild von Ihrem System entfernen möchten, können Sie Folgendes verwenden:
docker image rm nginx:alpineUntagged: nginx:alpine
Untagged: nginx@sha256:b89a6ccbda39576ad23fd079978c967cecc6b170db6e7ff8a769bf2259a71912
Deleted: sha256:7d0cdcc60a96a5124763fddf5d534d058ad7d0d8d4c3b8be2aefedf4267d0270
Deleted: sha256:05a0eaca15d731e0029a7604ef54f0dda3b736d4e987e6ac87b91ac7aac03ab1
Deleted: sha256:c6bbc4bdac396583641cb44cd35126b2c195be8fe1ac5e6c577c14752bbe9157
Deleted: sha256:35789b1e1a362b0da8392ca7d5759ef08b9a6b7141cc1521570f984dc7905eb6
Deleted: sha256:a3efaa65ec344c882fe5d543a392a54c4ceacd1efd91662d06964211b1be4c08
Deleted: sha256:3e207b409db364b595ba862cdc12be96dcdad8e36c59a03b7b3b61c946a5741aHinweis: Bitte beachten Sie unseren Leitfaden zur Installation von Docker auf Ubuntu – Schritt-für-Schritt-Anleitung für eine ausführlichere Übersicht zu Docker-Befehlen.
Schritt 5 — Erstellen einer Multi-Service-Anwendung
Die wahre Stärke von Docker Compose liegt darin, mehrere zusammenarbeitende Dienste zu verwalten. Das Nginx-Beispiel war ein einzelner Dienst. Lassen Sie uns eine praktischere, mehrteilige Anwendung erstellen: eine WordPress-Website, die mit einer MySQL-Datenbank verbunden ist.
Dieses Setup umfasst zwei Dienste: wordpress (führt die Anwendung aus) und db (führt die Datenbank aus). Wir werden auch Docker-Volumes verwenden, um sicherzustellen, dass die Daten der Datenbank erhalten bleiben, selbst wenn der Container entfernt wird.
Lass uns ein neues Verzeichnis für diese Anwendung erstellen:
mkdir -p ~/compose-demo/wordpressapp
cd ~/compose-demo/wordpressappFür dieses Beispiel benötigen wir keine lokalen Dateien, da die Bilder alle erforderliche Software enthalten werden.
Erstellen Sie eine neue docker-compose.yml-Datei:
nano docker-compose.ymlFügen Sie die folgende Konfiguration ein. Diese Datei ist komplexer, daher werden wir jeden Teil untersuchen.
services:
db:
image: mysql:8.0
container_name: mysql_db
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: <^your_root_password_here<^>
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress_user
MYSQL_PASSWORD: <^your_wordpress_password_here<^>
restart: unless-stopped
wordpress:
image: wordpress:latest
container_name: wordpress_app
ports:
- "8001:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress_user
WORDPRESS_DB_PASSWORD: <^your_wordpress_password_here<^>
WORDPRESS_DB_NAME: wordpress
volumes:
- ./wp_content:/var/www/html/wp-content
depends_on:
- db
restart: unless-stopped
volumes:
db_data:Hinweis: Wir haben die Werte für das Passwort hier zu Illustrationszwecken fest codiert. Bei der Nutzung in einer realen Umgebung sollten Sie unbedingt Umgebungsvariablen in einer .env-Datei verwenden, um die Preisgabe Ihrer Zugangsdaten zu vermeiden.
Speichern Sie die Datei und schließen Sie sie. Denken Sie daran, die Platzhalter <^...^> durch starke, sichere Passwörter zu ersetzen.
Lassen Sie uns die neuen Richtlinien in dieser Datei durchgehen:
services: Dieser Block definiert immer noch unsere Container. Wir haben jetzt zwei:dbundwordpress.image: Wir verwendenmysql:8.0für die Datenbank und daswordpress:latest-Image für die Anwendung.container_name: Damit wird ein bestimmter, für Menschen lesbarer Name für den Container festgelegt, der leichter zu referenzieren ist als die automatisch generierten.environment: Dies ist eine Liste von Umgebungsvariablen, die an den Container übergeben werden. Dasmysql-Image verwendet diese, um das Root-Passwort festzulegen und eine anfängliche Datenbank sowie einen Benutzer zu erstellen. Daswordpress-Image verwendet sie, um zu wissen, wie es eine Verbindung zu seiner Datenbank herstellen kann.Volumes(Service-Ebene):- Für den
db-Dienst wirddb_data:/var/lib/mysqlverwendet, um ein von Docker verwaltetes Volume mit dem Namendb_dataauf das MySQL-Datenverzeichnis innerhalb des Containers zuzuordnen. So bleiben Ihre Daten sicher.
- Für den
- Für den
wordpress-Dienst ordnet./wp_content:/var/www/html/wp-contentein lokales Verzeichnis (wp_content) dem WordPress-Content-Verzeichnis zu. Dadurch können Sie Themes und Plugins direkt von Ihrem Host-Rechner aus bearbeiten.
depends_on: Dies teilt Compose mit, dass der db-Dienst vor dem Start des wordpress-Dienstes gestartet werden soll. Das ist wichtig, da WordPress fehlschlägt, wenn es seine Datenbank beim Start nicht finden kann.volumes (oberste Ebene): Dieser Block definiert die benannten Volumes. db_data: erstellt ein von Docker verwaltetes Volume, was die bevorzugte Methode zur Handhabung persistenter Daten ist.Bringen Sie nun diese Multi-Service-Anwendung hoch:
docker compose up -dCompose wird sowohl die mysql- als auch die wordpress-Images herunterladen und dann die Container erstellen, wobei der db-Dienst zuerst gestartet wird.
Creating network "compose-demo_default" with the default driver
Creating volume "compose-demo_db_data" with default driver
Pulling db (mysql:8.0)...
...
Pulling wordpress (wordpress:latest)...
...
Creating mysql_db ... done
Creating wordpress_app ... doneSie können nun auf Ihre neue WordPress-Website zugreifen, indem Sie in Ihrem Browser zu localhost:8001 oder <^your_server_domain_or_IP<^>:8001 navigieren. Sie sollten den WordPress-Installationsbildschirm sehen. Für ein detaillierteres Beispiel schauen Sie sich unseren Artikel über die Installation von WordPress mit Docker Compose an.
Schritt 6 — Verwendung von Docker Compose für die KI/ML-Entwicklung
Über Webanwendungen hinaus ist Docker Compose ein äußerst nützliches Werkzeug zur Erstellung reproduzierbarer Datenwissenschafts- und Machine-Learning-(AI/ML)-Umgebungen. AI/ML-Projekte sind bekannt für ihre komplexen Abhängigkeiten, einschließlich spezifischer Python-Versionen, Bibliotheken wie TensorFlow oder PyTorch sowie systemweiter Treiber wie das NVIDIA CUDA Toolkit. Docker Compose erfasst diese gesamte Umgebung in Konfigurationsdateien und löst das Problem „auf meinem Rechner funktioniert es“, was für reproduzierbare Forschung entscheidend ist.
In diesem Beispiel erstellen Sie eine Multi-Service-AI/ML-Umgebung, die aus Folgendem besteht:
- JupyterLab: Ein Container für interaktive Entwicklung, erstellt aus einem benutzerdefinierten
Dockerfile. - PostgreSQL: Ein Datenbank-Container zur Speicherung von Experimentergebnissen und Metadaten.
- GPU-Zugriff: Der JupyterLab-Container wird so konfiguriert, dass er auf die NVIDIA-GPU des Host-Computers zugreifen kann, was eine gängige Voraussetzung für das Training von Modellen ist.
Voraussetzung: Für dieses Beispiel wird eine NVIDIA-GPU auf Ihrem Host-Rechner und das NVIDIA Container Toolkit benötigt. Ohne diese wird der Container beim Anfordern von GPU-Ressourcen nicht gestartet.
Dateistruktur
Erstellen Sie zunächst ein Verzeichnis für Ihr Projekt. Darin erstellen Sie eine docker-compose.yml-Datei, ein jupyter-Verzeichnis, eine Dockerfile für Jupyter und eine requirements.txt-Datei. Die Struktur sollte ungefähr wie folgt aussehen:
ai-project/
├── docker-compose.yml
└── jupyter/
├── Dockerfile
└── requirements.txtErstellen der Komponenten-Dateien
1. Die requirements.txt-Datei
Diese Datei listet die Python-Pakete für Ihre Data-Science-Umgebung auf.
nano jupyter/requirements.txtFügen Sie die benötigten Pakete hinzu. Für dieses Beispiel werden wir Bibliotheken für Datenmanipulation, Datenbankverbindung und ein Deep-Learning-Framework einbeziehen.
pandas
scikit-learn
tensorflow
jupyterlab
psycopg2-binarySpeichern und schließen Sie die Datei.
2. Die Dockerfile
Diese Datei definiert Ihren benutzerdefinierten JupyterLab-Dienst. Sie verwendet ein offizielles Jupyter-Image als Basis und installiert die Pakete aus requirements.txt.
nano jupyter/DockerfileFügen Sie den folgenden Inhalt ein:
# Start from a base image that includes Jupyter and scientific libraries
FROM jupyter/scipy-notebook:latest
# Copy our local requirements file into the container
COPY requirements.txt /tmp/requirements.txt
# Install the Python packages
RUN pip install --no-cache-dir -r /tmp/requirements.txtDiese Datei weist Docker an, jupyter/scipy-notebook als Ausgangspunkt zu verwenden, Ihre requirements.txt in den Container zu kopieren und anschließend pip zu verwenden, um die Pakete zu installieren.
Die Umgebung mit docker-compose.yml definieren
Erstellen Sie nun die Hauptdatei docker-compose.yml. Diese Datei wird sowohl den db-Dienst als auch Ihren benutzerdefinierten jupyter-Dienst orchestrieren.
nano docker-compose.ymlFügen Sie die folgende Konfiguration ein und ersetzen Sie die Platzhalter <^...^> durch Ihre eigenen sicheren Zugangsdaten.
services:
db:
image: postgres:15-alpine
container_name: ai_postgres_db
environment:
POSTGRES_USER: <^your_db_user^>
POSTGRES_PASSWORD: <^your_db_pass^>
POSTGRES_DB: experiments
healthcheck:
test: ["CMD-SHELL", "pg_isready -U <^your_db_user^> -d experiments"]
interval: 10s
timeout: 5s
retries: 5
volumes:
- postgres_data:/var/lib/postgresql/data
restart: unless-stopped
networks:
- ai_net
jupyter:
build: ./jupyter
container_name: ai_jupyter_lab
ports:
- "8888:8888"
volumes:
- ./notebooks:/home/jovyan/work
environment:
- POSTGRES_HOST=db
- POSTGRES_USER=<^your_db_user^>
- POSTGRES_PASSWORD=<^your_db_pass^>
- POSTGRES_DB=experiments
restart: unless-stopped
networks:
- ai_net
depends_on:
db:
condition: service_healthy
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
volumes:
postgres_data:
name: ai_project_data
networks:
ai_net:
driver: bridgeDiese Konfigurationsdatei führt mehrere wichtige Konzepte ein:
build: ./jupyter: Dies teilt Docker Compose mit, ein benutzerdefiniertes Image für denjupyter-Dienst zu erstellen. Es sucht nach einerDockerfileim angegebenen./jupyter-Verzeichnis.volumes: - ./notebooks:/home/jovyan/work: Dadurch wird ein lokales Verzeichnis namensnotebooksin den Container eingebunden. So wird sichergestellt, dass alle von Ihnen erstellten Jupyter-Notebooks direkt auf Ihrem Host-Rechner gespeichert werden und auch nach Entfernen des Containers erhalten bleiben.healthcheck: Wie im Abschnitt zur Fehlerbehebung zu sehen ist, überprüft dieser Check, dass derdb-Dienst nicht nur läuft, sondern bereit ist, Verbindungen anzunehmen, bevor andere Dienste starten.depends_on: ... condition: service_healthy: Dies teilt demjupyter-Dienst mit, dass er warten soll, bis der Healthcheck desdb-Dienstes bestanden ist, bevor er startet.deploy.resources.reservations.devices: Dies ist der Block, der den Zugriff auf die GPU anfordert.driver: nvidia: Gibt den zu verwendenden Host-Treiber an.
count: 1: Fordert eine GPU an.capabilities: [gpu]: Stellt sicher, dass der Container die notwendigen Funktionen besitzt, um die GPU zu verwenden.
Den KI/ML-Umgebung betreiben
Mit Ihren Dateien an ihrem Platz sind Sie bereit, die Dienste zu erstellen und auszuführen.
Führen Sie aus Ihrem
ai-project-Verzeichnis den Befehldocker compose upaus. Sie müssen beim ersten Mal das--build-Flag hinzufügen, um Compose anzuweisen, Ihr benutzerdefiniertesjupyter-Image zu erstellen.docker compose up -d --buildCompose wird zuerst das
jupyter-Image erstellen (was einige Minuten dauern kann, da TensorFlow heruntergeladen wird), dann daspostgres-Image ziehen und schließlich beide Container starten.[+] Building 5.8s (9/9) FINISHED => [internal] load build definition from Dockerfile ... [+] Running 3/3 ✔ Network ai-project_ai_net Created ✔ Container ai_postgres_db Started ✔ Container ai_jupyter_lab StartedSie können jetzt auf die JupyterLab-Oberfläche zugreifen, indem Sie in Ihrem Browser zu
http://localhost:8888(oder<^Ihre_Server_IP^>:8888) navigieren. Sie werden nach einem Token gefragt, das Sie aus den Container-Protokollen erhalten können:docker compose logs jupyterSuchen Sie nach einer Zeile, die ähnlich aussieht wie
http://127.0.0.1:8888/lab?token=a1b2c3d4e5f6...Innerhalb eines Jupyter-Notebooks können Sie jetzt eine Verbindung zu Ihrer Datenbank über den Hostnamen
dbund die von Ihnen angegebenen Zugangsdaten herstellen. Ihre Umgebung hat außerdem Zugriff auf die GPU des Hosts für das Modelltraining.
Skalierung von Diensten und Verwendung benutzerdefinierter Netzwerke
Docker Compose beinhaltet Funktionen zum Skalieren von Diensten und zur Verwaltung der Netzwerke, über die sie kommunizieren.
Dienstskalierung mit Replikaten
Stellen Sie sich vor, Ihr Nginx-Webserver aus Schritt 2 bekommt zu viel Verkehr. Sie können den web-Dienst skalieren, um mehrere Container-Instanzen auszuführen. Docker Compose kann dies automatisch verwalten.
Es gibt zwei Hauptmöglichkeiten, einen Service zu skalieren.
1. Verwendung des replicas-Schlüssels (Bevorzugt in v2)
Sie können die gewünschte Anzahl von Instanzen direkt in Ihrer docker-compose.yml-Datei mit den Schlüsseln deploy und replicas festlegen. Diese Funktion war ursprünglich Teil von Docker Swarm, ist jetzt jedoch auch für Standard-Compose-Bereitstellungen verfügbar.
Ändern Sie Ihre Nginx-docker-compose.yml aus Schritt 2:
services:
web:
image: nginx:alpine
ports:
- "8000:80"
volumes:
- ./app:/usr/share/nginx/html
deploy:
replicas: 3Wenn Sie docker compose up -d ausführen, erstellt Compose drei web-Container. Allerdings gibt es ein Problem: Alle drei werden versuchen, an den Host-Port 8000 zu binden. Dies führt beim zweiten und dritten Container zu einem Fehler „Port ist bereits zugewiesen“. Um dies in einer Produktionsumgebung zu lösen, würden Sie die ports-Zuordnung vom web-Dienst entfernen. Auf diese Weise sind die Web-Container nur innerhalb des Docker-Netzwerks zugänglich. Ein separater Load-Balancer-Dienst wäre dann der einzige mit einem öffentlichen Port. Er würde den Traffic an die drei Web-Replikate verteilen.
Ein Beispiel für eine Konfiguration würde so aussehen (dies ist ein fortgeschrittenes Beispiel):
services:
web:
image: nginx:alpine
# No 'ports' mapping here.
# The service is only accessible inside the 'web-net' network.
volumes:
- ./app:/usr/share/nginx/html
deploy:
replicas: 3
networks:
- web-net
load_balancer:
image: nginx:latest
ports:
- "80:80" # The load_balancer is the only service with a public port.
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf # A config file that load balances to 'web'.
networks:
- web-net
depends_on:
- web
networks:
web-net:In dieser Konfiguration hört der load_balancer auf Port 80 und leitet Anfragen intern an web_1, web_2 und web_3 weiter.
Dieser replicas-Schlüssel ist am nützlichsten, wenn er zusammen mit einem Reverse-Proxy (wie Traefik oder einer anderen Nginx-Instanz) verwendet wird, der Anfragen zwischen den Replikaten innerhalb des Docker-Netzwerks load-balancen kann, ohne dass jedes Replikat einen Port auf dem Host freigeben muss.
2. Verwendung des --scale-Flags
Eine gängige Methode zur Skalierung ist das --scale-Flag, ein Überbleibsel aus Compose v1. Dieses Flag wird zur Laufzeit angewendet und überschreibt jeden replicas-Schlüssel.
Sie müssen jedoch vorsichtig mit Portdefinitionen sein. Wenn Ihr Dienst eine feste Host-Port-Zuordnung definiert (z. B. "8000:80"), führt das Ausführen von docker compose up --scale zu einem Fehler für den zweiten und dritten Container, da alle versuchen, denselben Host-Port zu binden.
Um --scale für Dienste zu verwenden, die Ports freigeben, dürfen Sie keine feste Host-Port-Zuordnung verwenden.
Option 1: Auf zufällige Host-Ports zuordnen (Gut für die Entwicklung)
Sie können Ihre
docker-compose.ymlso ändern, dass nur der Container-Port angegeben wird. Dies teilt Docker mit, den Port 80 in jedem Container auf einen zufälligen, verfügbaren Port auf Ihrem Host-Rechner zuzuordnen.services: web: image: nginx:alpine ports: - "80" # No fixed host port volumes: - ./app:/usr/share/nginx/htmlWenn Sie nun den Skalierungsbefehl ausführen:
docker compose up -d --scale web=3Führen Sie
docker compose psaus, um das Ergebnis zu sehen. Jeder Container wird auf einem anderen, zufällig zugewiesenen Host-Port laufen:Name Command State Ports ---------------------------------------------------------------------------------- compose-demo_web_1 /docker-entrypoint.sh ngin ... Up 0.0.0.0:49154->80/tcp compose-demo-web_2 /docker-entrypoint.sh ngin ... Up 0.0.0.0:49155->80/tcp compose-demo-web_3 /docker-entrypoint.sh ngin ... Up 0.0.0.0:49156->80/tcpOption 2: Verwenden Sie einen Reverse-Proxy (Gut für die Produktion)
Die andere Lösung, wie im Abschnitt
replicaserwähnt, besteht darin, dieports-Direktive vollständig aus demweb-Dienst zu entfernen. Sie würden dann einen separaten Load-Balancer-Container verwenden (der den einzigen öffentlichen Port hat), um den Datenverkehr zu den skalierten Replikaten innerhalb des Docker-Netzwerks zu verwalten und zu verteilen.Um alle drei Container zu stoppen und zu entfernen, bleibt der Befehl derselbe:
docker compose down
docker-compose.yml - Korrekt für --scale
Benutzerdefinierte Netzwerkkonfiguration
Standardmäßig erstellt Docker Compose ein einzelnes bridge-Netzwerk für Ihre Anwendung. Jeder Dienst in der Datei ist damit verbunden, wodurch der wordpress-Container den db-Container allein durch die Verwendung seines Dienstnamens (db) finden konnte.
Sie können jedoch eigene benutzerdefinierte Netzwerke für bessere Isolation und Kontrolle definieren.
Lassen Sie uns das WordPress-Beispiel so ändern, dass ein eigenes bridge-Netzwerk verwendet wird.
services:
db:
image: mysql:8.0
...
networks:
- app_net
wordpress:
image: wordpress:latest
...
ports:
- "8001:80"
depends_on:
- db
networks:
- app_net
volumes:
db_data:
networks:
app_net:
driver: bridgeDas haben wir hinzugefügt:
networks(oberste Ebene): Dies definiert ein neues Netzwerk mit dem Namenapp_netund gibt an, dass es den Standard-bridge-Treiber verwenden soll.Netzwerke(Service-Ebene): Unter sowohldbals auchwordpressverbindet dieser Schlüssel sie mit unseremapp_net-Netzwerk.
Wenn Sie einen dritten Dienst (wie ein Analysetool) hätten, den Sie nicht mit app_net verbinden, wäre er vollständig isoliert und könnte nicht mit den db- oder wordpress-Containern kommunizieren.
Für Multi-Host-Clustering mit Docker Swarm würden Sie den driver von bridge auf overlay ändern. Der bridge-Treiber dient der Kommunikation zwischen Containern auf einem einzigen Host, was der Standard für die meisten Docker-Compose-Anwendungsfälle ist.
Verwendung modularer Konfigurationsdateien
Wenn Ihre Anwendungen wachsen, kann Ihre docker-compose.yml-Datei groß und schwer zu verwalten werden. Docker Compose unterstützt eine include-Direktive, mit der Sie Ihre Konfiguration auf mehrere Dateien aufteilen können.
Stellen Sie sich vor, Sie möchten Ihre WordPress- und Datenbankdefinitionen trennen und vielleicht eine gemeinsame docker-compose.override.yml für entwicklungsspezifische Einstellungen haben (wie das Binden eines Ports an die Datenbank).
Ihre Verzeichnisstruktur könnte folgendermaßen aussehen:
compose-demo/
├── docker-compose.yml
├── docker-compose.db.yml
├── docker-compose.web.ymlDiese Datei wird nur den db-Dienst definieren.
services:
db:
image: mysql:8.0
container_name: mysql_db
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: <^your_root_password_here<^>
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress_user
MYSQL_PASSWORD: <^your_wordpress_password_here<^>
restart: unless-stopped
volumes:
db_data:Diese Datei wird nur den wordpress-Dienst definieren.
services:
wordpress:
image: wordpress:latest
container_name: wordpress_app
ports:
- "8001:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress_user
WORDPRESS_DB_PASSWORD: <^your_wordpress_password_here<^>
WORDPRESS_DB_NAME: wordpress
volumes:
- ./wp_content:/var/www/html/wp-content
depends_on:
- db
restart: unless-stoppedJetzt wird deine Haupt-docker-compose.yml-Datei sehr einfach. Sie verwendet einfach include, um die anderen Dateien einzubinden.
include:
- docker-compose.db.yml
- docker-compose.web.ymlWenn Sie docker compose up -d ausführen, liest Compose alle drei Dateien, führt die Konfigurationen zusammen und startet die db- und wordpress-Dienste genau so, als wären sie in einer einzigen Datei definiert. Dieser Ansatz macht Ihre Konfiguration wesentlich modularer und wiederverwendbarer.
Hinweis: Die include:-Direktive erfordert Docker Compose v2.20 oder höher. Wenn Ihr System eine ältere Version verwendet, können Sie Dateien mit docker compose -f docker-compose.db.yml -f docker-compose.web.yml up kombinieren.
Migration von docker-compose (v1) zu docker compose (v2)
Der docker compose-Befehl, den Sie in Schritt 1 installiert haben, ist „Compose v2.“. Es handelt sich um ein auf Go basierendes Plugin, das direkt in die Docker-CLI integriert ist.
Die Originalversion, „Compose v1“, war ein separates Python-Tool, das mit docker-compose (mit Bindestrich) aufgerufen wurde. Ab Juli 2023 wird Compose v1 nicht mehr unterstützt und ist veraltet.
Wesentliche Änderungen und Abwärtskompatibilität
- Der Befehl: Die offensichtlichste Änderung ist der Befehl. Der Bindestrich (
docker-compose) ist jetzt ein Leerzeichen (docker compose). - Installation: v1 wurde mit
pipinstalliert. v2 ist in Docker Desktop enthalten oder wird als CLI-Plugin installiert, wie Sie es in Schritt 1 getan haben. - YAML-Dateien: Ihre
docker-compose.yml-Dateien sind nahezu 100 % abwärtskompatibel. Compose v2 unterstützt Dateien der Version3.xvollständig. Sie müssen Ihre YAML-Dateien für die Migration nicht ändern, nur Ihre Befehle. --project-nameFlag: Das-pFlag funktioniert weiterhin, aber das vollständige Flag lautet jetzt--project-nameanstelle von--project_name.
Befehls-Migrationshandbuch
Die meisten Befehle sind identisch, nur ohne den Bindestrich. Hier ist eine Tabelle, die gängige v1-Befehle mit ihren v2-Entsprechungen vergleicht.
docker-compose (v1) Befehl | docker compose (v2) Befehl | Notizen |
|---|---|---|
| | Keine Änderung der Syntax. |
| | Keine Änderung der Syntax. |
| | Keine Änderung der Syntax. |
| | Keine Änderung der Syntax. |
| | Keine Änderung der Syntax. |
| | Keine Änderung der Syntax. |
| | Keine Änderung der Syntax. |
| | run erstellt einen neuen Container. exec führt in einem bestehenden Container aus. |
| | Das --scale-Flag wird in v2 weiterhin unterstützt. |
Wie Sie sehen können, ist für den meisten Alltagsgebrauch die einzige Änderung docker-compose -> docker compose. Wenn Sie Skripte verwenden, können Sie diese einfach aktualisieren, indem Sie den Bindestrich entfernen.
Wenn Sie noch die alte docker-compose v1 installiert haben, können Sie sie entfernen, um Verwirrung zu vermeiden:
sudo pip3 uninstall docker-composeOder, wenn es mit apt installiert wurde:
sudo apt remove docker-composeFehlerbehebung bei häufigen Docker Compose-Problemen
Wenn Sie mit Docker Compose arbeiten, können Probleme im Zusammenhang mit Dateisyntax, Berechtigungen oder Konflikten zur Laufzeit von Containern auftreten. Die meisten Probleme lassen sich diagnostizieren und beheben, indem Sie systematisch Ihre Konfiguration, Berechtigungen und Containerprotokolle überprüfen.
Werfen wir einen Blick auf einige der häufigsten Fehler und ihre Lösungen.
Zugriff verweigert (Docker-Socket)
Dies ist einer der häufigsten Fehler bei neuen Docker-Nutzern. Sie führen docker compose up aus und sehen eine Fehlermeldung über den Docker-Daemon-Socket.
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sockProblem: Ihr Nicht-Root-Benutzer hat keine Berechtigung, mit dem Docker-Daemon zu kommunizieren, der als
rootläuft.Lösung: Sie müssen Ihren Benutzer zur
docker-Gruppe hinzufügen, die während der Docker-Installation erstellt wurde.Fügen Sie Ihren Benutzer der
docker-Gruppe hinzu:sudo usermod -aG docker ${USER}
Damit die neue Gruppenmitgliedschaft wirksam wird, müssen Sie sich abmelden und wieder anmelden.
Alternativ können Sie die Gruppenänderungen für Ihre aktuelle Terminalsitzung aktivieren, indem Sie Folgendes eingeben:
newgrp docker
Dies sollte alle Berechtigungsfehler im Zusammenhang mit dem Docker-Socket beheben.
YAML-Syntax- und Einrückungsfehler
Docker Compose kann nicht ausgeführt werden und meldet, dass Ihre docker-compose.yml-Datei ungültig ist.
ERROR: The Compose file './docker-compose.yml' is invalid because:
services.web.ports contains an invalid type, it should be a listOder :
mapping values are not allowed in this context at line 5- Problem: Die
docker-compose.yml-Datei ist auf eine strikte YAML-Syntax angewiesen. Der häufigste Fehler ist eine falsche Einrückung. YAML verwendet Leerzeichen, keine Tabs, um die Struktur zu definieren. Lösung: Überprüfen Sie sorgfältig die Einrückung Ihrer
docker-compose.yml-Datei.- Der Standard sind zwei Leerzeichen pro Einrückungsebene.
- Stellen Sie sicher, dass alle Schlüssel auf derselben Ebene (wie
version,services,volumes) in der gleichen Spalte beginnen. - Stellen Sie sicher, dass alle Unter-Schlüssel (wie
image,ports,volumesunter einem Dienst) zwei Leerzeichen mehr als ihr übergeordneter Dienst (z. B.web) eingerückt sind. - Verwenden Sie einen Code-Editor mit einem YAML-Linter, um Syntaxfehler automatisch hervorzuheben.
Portkonflikte
Du versuchst, deine Umgebung zu starten, aber der Befehl schlägt mit einer Fehlermeldung fehl, dass die Adresse bereits verwendet wird.
Error starting userland proxy: listen tcp 0.0.0.0:8000: bind: address already in useProblem: Ein anderer Prozess auf Ihrem Host-Rechner lauscht bereits auf dem Port, den Sie zuzuordnen versuchen (in diesem Fall Port
8000). Dies ist oft ein anderer Docker-Container oder ein lokaler Entwicklungsserver.Lösung: Sie haben zwei Möglichkeiten:
Stoppen Sie den anderen Prozess. Sie können den Prozess, der den Port verwendet, mit diesem Befehl finden:
sudo lsof -i :8000Wenn es ein anderer Docker-Container ist, stoppen Sie ihn mit
docker stop <container_id>.
Ändern Sie den Host-Port in Ihrer
docker-compose.yml-Datei. Dies ist oft die einfachste Lösung. Ändern Sie dieports-Zuordnung von"8000:80"auf einen anderen Port, zum Beispiel"8001:80".... ports: - "8001:80" # Changed from 8000 ...
docker-compose.yml
Dienst schlägt fehl mit Connection Refused (depends_on)
In einer Multi-Service-Anwendung (wie im Beispiel mit WordPress und MySQL) startet der wordpress-Container, aber in seinen Logs wird Connection refused oder MySQL server has gone away angezeigt, wenn versucht wird, eine Verbindung zum db-Dienst herzustellen.
Problem: Sie haben
depends_onverwendet, aber diese Direktive wartet nur darauf, dass derdb-Container gestartet wird. Sie wartet nicht darauf, dass die MySQL-Applikation innerhalb des Containers vollständig initialisiert ist und Verbindungen akzeptieren kann.Lösung: Die Anwendung (in diesem Fall WordPress) muss so konfiguriert werden, dass sie ihre Verbindung erneut versucht. Die meisten modernen Images haben diese Wiederholungslogik bereits integriert. Für Images, die dies nicht tun, müssen Sie eine Healthcheck-Implementierung vornehmen.
Sie können Ihrem
db-Dienst einehealthcheckhinzufügen. Derdepends_on-Eintrag deswordpress-Dienstes kann dann so konfiguriert werden, dass er auf eine „gesunde“ Datenbank wartet, nicht nur darauf, dass sie „gestartet“ ist.
Beispiel-Healthcheck für MySQL:
services:
db:
image: mysql:8.0
...
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p<^your_root_password_here<^>"]
interval: 10s
timeout: 5s
retries: 5
wordpress:
image: wordpress:latest
...
depends_on:
db:
condition: service_healthy # This now waits for the healthcheck
...Fehler bei Volumes und Bind-Mounts
In den Protokollen Ihres Containers können Berechtigungsfehler auftreten, oder Sie stellen fest, dass das Datenverzeichnis Ihres Containers leer ist.
Datei-/Verzeichnisberechtigungen
Problem: Der Container läuft als ein bestimmter Benutzer (z. B.
www-datamit der Benutzer-ID 33), aber das Host-Verzeichnis, das Sie eingebunden haben, gehört Ihrem Benutzer (z. B.ubuntumit der Benutzer-ID 1000). Der Benutzer des Containers hat keine Berechtigung, in das Host-Verzeichnis zu schreiben.Lösung: Ändern Sie den Besitz des Host-Verzeichnisses, damit er mit der Benutzer-ID im Container übereinstimmt. Sie können die Benutzer-ID des Containers herausfinden, indem Sie
docker compose exec <service_name> idausführen. Zum Beispiel, wenn die ID 33 ist (üblich fürwww-data):sudo chown -R 33:33 ./wp_content
Relative Pfadprobleme
Problem: Ihre
docker-compose.ymlverwendet einen relativen Pfad wie./app, aber Ihreindex.html-Datei wird nicht bereitgestellt.Lösung: Docker Compose interpretiert relative Pfade aus dem Verzeichnis, in dem Sie den Befehl
docker compose upausführen. Führen Sie Compose-Befehle stets aus dem gleichen Verzeichnis aus, das Ihredocker-compose.yml-Datei enthält.
Netzwerk- und Diensterkennung
Die Protokolle Ihres Anwendungscontainers zeigen Host nicht gefunden oder Konnte Host nicht auflösen: db.
- Problem: Dein
wordpress-Container kann dendb-Container im Netzwerk nicht finden. Lösung: Standardmäßig erstellt Docker Compose ein Netzwerk und verbindet alle Dienste damit. Dienste können einander über ihre Dienst-Namen finden.
Dienstnamen überprüfen: Stellen Sie sicher, dass der Hostname in der Konfiguration Ihrer Anwendung (z. B. die Umgebungsvariable
WORDPRESS_DB_HOST) genau derselbe ist wie der Dienstname in Ihrerdocker-compose.yml(z. B.db).
Netzwerk überprüfen: Verwenden Sie
docker compose ps, um den Namen Ihres Projekts zu finden (z. B.compose-demo). Anschließend überprüfen Sie das Standardnetzwerk:docker network inspect compose-demo_defaultDie JSON-Ausgabe listet alle Container auf, die an dieses Netzwerk angeschlossen sind. Wenn einer Ihrer Dienste fehlt, überprüfen Sie Ihre
docker-compose.ymlauf benutzerdefiniertenetworks-Konfigurationen, die ihn isolieren könnten.
Befehlsabweichung (v1 vs. v2)
Sie geben docker-compose up (mit einem Bindestrich) ein und sehen einen Fehler „Befehl nicht gefunden“.
docker-compose: command not found- Problem: Sie versuchen, den Befehl für Compose v1 zu verwenden, ein veraltetes Python-Tool. Diese Anleitung installiert Compose v2, ein Plugin, das direkt in die Docker-CLI integriert ist.
- Lösung: Verwenden Sie den richtigen Befehl, indem Sie den Bindestrich (
-) durch ein Leerzeichen ersetzen.
docker-compose (v1) | docker compose (v2) |
|---|---|
docker-compose up | docker compose up |
docker-compose down | docker compose down |
docker-compose ps | docker compose ps |
docker-compose logs | docker compose logs |
Verwenden Sie beim Befolgen dieser Anleitung immer docker compose (mit Leerzeichen).
Häufig gestellte Fragen
1. Wofür wird Docker Compose verwendet?
Docker Compose ist ein Tool zum Definieren und Ausführen von Multi-Container-Docker-Anwendungen.
Es verwendet eine einzelne YAML-Datei (standardmäßig docker-compose.yml), um alle Komponenten Ihrer Anwendung zu konfigurieren, die als Services bezeichnet werden. Diese Datei definiert auch die Netzwerke, die den Services die Kommunikation untereinander ermöglichen, sowie die Volumes, die für persistente Daten verwendet werden.
Mit dieser einzigen Datei können Sie Ihren gesamten Anwendungs-Stack mit einfachen Befehlen verwalten:
docker compose upstartet und führt Ihre gesamte Anwendung aus, einschließlich aller angegebenen Container, Netzwerke und Volumes.docker compose downstoppt und entfernt alle von Ihrer Anwendung erstellten Container, Netzwerke und Volumes.
Es ist besonders nützlich für die Verwaltung von Anwendungen, die mehrere Komponenten benötigen, wie beispielsweise eine Website, die einen Webserver (wie Nginx), ein Anwendungs-Backend (wie WordPress) und eine Datenbank (wie MySQL) benötigt.
2. Wie installiere ich Docker Compose auf Ubuntu?
Die empfohlene Methode ist, Docker Compose als Plugin für die Docker-CLI zu installieren. Dies erfolgt durch die Installation des docker-compose-plugin-Pakets aus dem offiziellen apt-Repository von Docker.
Stellen Sie zunächst sicher, dass Sie der offiziellen Docker-Dokumentation gefolgt sind, um das
apt-Repository von Docker auf Ihrem Ubuntu-System einzurichten.Aktualisiere deine Paketliste:
sudo apt updateInstallieren Sie das Docker Compose-Plugin:
sudo apt install docker-compose-pluginÜberprüfen Sie die Installation, indem Sie die Version prüfen. Der Befehl verwendet ein Leerzeichen, keinen Bindestrich.
docker compose version
3. Wie aktualisiere ich Docker Compose auf die neueste Version?
Da Docker Compose (v2) als Systempaket über apt installiert ist, können Sie es über den standardmäßigen Ubuntu-Software-Update-Prozess aktualisieren.
Aktualisieren Sie Ihren lokalen Paketindex:
sudo apt updateFühren Sie ein systemweites Upgrade durch, das das Compose-Plugin einschließt:
sudo apt upgradeAlternativ, wenn Sie nur das Plugin selbst aktualisieren möchten, können Sie Folgendes ausführen:
sudo apt install --only-upgrade docker-compose-plugin
4. Kann Docker Compose in Produktionsumgebungen eingesetzt werden?
Ja, Docker Compose wird häufig in der Produktion verwendet, insbesondere für Anwendungen, die auf einem einzelnen Host laufen.
Es bietet eine einfache Möglichkeit, die Dienste, Netzwerke und Volumes Ihrer Anwendung zu definieren, bereitzustellen und deren Lebenszyklus zu verwalten. Für eine Einzelserverbereitstellung ist es eine sehr effektive und leicht zu verwaltende Lösung.
Für komplexere Szenarien, die die Koordination von Containern über mehrere Hosts (ein Cluster) erfordern, sind andere Tools üblicher. Dazu gehören Docker Swarm (das eine ähnliche Compose-Datei-Syntax verwendet) und Kubernetes (der Industriestandard für groß angelegte Container-Orchestrierung).
5. Was ist der Unterschied zwischen Docker und Docker Compose?
Diese Tabelle zeigt die wichtigsten Unterschiede zwischen der Docker CLI und der Docker Compose CLI auf.
| Funktion | docker (Docker-Engine) | docker compose (Compose-Plugin) |
|---|---|---|
| Umfang | Verwaltet einzelne Docker-Objekte. | Verwaltet eine vollständige Multi-Container-Anwendung als eine einzelne Einheit. |
| Hauptverwendung | Images erstellen (docker build), einzelne Container ausführen (docker run), Container verwalten (docker ps), Images, Volumes und Netzwerke. | Orchestrierung mehrerer Dienste, die in einer docker-compose.yml-Datei definiert sind. |
| Befehle | Niedrigstufige Befehle, die auf ein Objekt fokussiert sind. Beispiel: docker run -d -p 80:80 -v ./:/app nginx | Hochrangige Befehle für die gesamte Anwendung. Beispiel: docker compose up |
| Analogie | Ein Baustein (ein einzelner Container). | Der Plan und der Bauleiter für das gesamte Gebäude (die Anwendung). |
Kurz gesagt, Sie verwenden docker, um mit einem einzelnen Container zu interagieren. Mit docker compose verwalten Sie Ihre gesamte Anwendungsumgebung (z. B. Web, App, DB) auf einmal.
6. Wie führe ich mehrere Container mit Docker Compose aus?
Sie betreiben mehrere Container, indem Sie sie in Ihrer docker-compose.yml-Datei als Services definieren.
Erstellen Sie eine Datei mit dem Namen
docker-compose.yml.Verwenden Sie in dieser Datei den Schlüssel
services:, um jeden Container zu definieren, den Sie ausführen möchten.Hier ist ein praktisches Beispiel, das zwei Container definiert und ausführt: eine WordPress-Website und eine MySQL-Datenbank.
services: db: # This is the first service (container) image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: <^your_password_here<^> MYSQL_DATABASE: wordpress volumes: - db_data:/var/lib/mysql wordpress: # This is the second service (container) image: wordpress:latest ports: - "8001:80" environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_PASSWORD: <^your_password_here<^> depends_on: - db volumes: db_data:Speichern Sie die Datei und öffnen Sie ein Terminal im selben Verzeichnis.
Führen Sie einen einzigen Befehl aus, um beide Container zu starten:
docker compose up -d
docker-compose.yml
Docker Compose wird die Datei lesen, ein gemeinsames Netzwerk für die Dienste erstellen, sowohl die mysql- als auch die wordpress-Images herunterladen und für jeden Dienst einen Container starten.
7. Warum Docker Compose für die Entwicklung verwenden?
Docker Compose ist ein Standardwerkzeug für Entwicklungsumgebungen, da es mehrere häufige Probleme löst.
Konstante Umgebungen: Es stellt sicher, dass jeder Entwickler in einem Team genau die gleichen Dienste (Datenbank, Cache, Webserver) mit genau den gleichen Versionen und Konfigurationen nutzt. Dies wird in der
docker-compose.yml-Datei definiert, die in die Versionskontrolle übernommen wird. Dadurch wird das Problem „bei mir funktioniert es“ beseitigt.Einfache Handhabung: Es ersetzt komplexe Installationsskripte und lange
docker run-Befehle. Ein Entwickler muss nurdocker compose upausführen, um den gesamten Anwendungsstack zu starten, unddocker compose down, um ihn zu stoppen.Service-Isolierung: Entwickler können an mehreren Projekten auf derselben Maschine arbeiten, ohne dass Abhängigkeitskonflikte auftreten. Projekt A kann PostgreSQL 9.6 verwenden und Projekt B PostgreSQL 14, da jede Datenbank in einem isolierten Container läuft, der von ihrer eigenen Compose-Datei verwaltet wird.
Einfache Integrationstests: Da Compose alle Abhängigkeiten einer Anwendung zusammen startet, schafft es eine ideale lokale Umgebung, um Integrationstests durchzuführen, die überprüfen, wie die Dienste miteinander interagieren.
Schlussfolgerung
In diesem Leitfaden haben Sie Docker Compose installiert und eine vollständige Multi-Container-Anwendung konfiguriert. Sie haben mit einer grundlegenden docker-compose.yml-Datei für einen Nginx-Webserver begonnen und sind zu einem komplexeren, realistischeren Stack übergegangen, der eine WordPress-Anwendung und eine MySQL-Datenbank umfasst. Sie haben gelernt, den gesamten Anwendungslebenszyklus zu verwalten, vom Erstellen und Ausführen von Diensten bis hin zum Stoppen und Entfernen dieser.
Sie sind nun mit den wichtigsten Konzepten zur effektiven Verwaltung von Anwendungen vertraut, einschließlich der Skalierung von Diensten, benutzerdefinierten Netzwerkkonfigurationen und der Aufteilung Ihrer Konfiguration in modulare Dateien mithilfe der include-Direktive. Wenn Sie dem Migrationsleitfaden und den Schritten zur Fehlerbehebung folgen, können Sie auch häufige Probleme wie Portkonflikte, „Zugriff verweigert“-Fehler und YAML-Syntaxfehler beheben. Die hier behandelten Fähigkeiten ermöglichen es Ihnen, konsistente, reproduzierbare Entwicklungsumgebungen zu erstellen und Single-Host-Anwendungen mit Zuversicht bereitzustellen.
Für eine vollständige Übersicht aller verfügbaren docker compose-Befehle werfen Sie einen Blick in die offizielle Dokumentation.
Für weitere Tutorials rund um Docker, schauen Sie sich die folgenden Artikel an:
- Wie man Docker auf Ubuntu installiert – Schritt-für-Schritt-Anleitung
- Wie man WordPress mit Docker Compose installiert
Danke, dass Sie mit der Linux-Console.net-Community lernen.

