
Docker Compose-Setups als eigenständige Container ausführen

Docker Compose ist großartig! Aber manchmal kann es nützlich sein, eine docker-compose.yml
-Datei zu entschlüsseln und jeden Container einzeln auszuführen.
Wir betreiben eine Hosting-Plattform für Container, unterstützen aber noch kein Docker Compose. Wir bekommen viele Anfragen, wie man Docker Compose-Setups deployen kann. Daher möchte ich dir den Prozess erklären, wie du eine Docker Compose-Datei dekonstruieren kannst, um jeden Container einzeln auszuführen.
Kurz gesagt:
Um Docker Compose-Setups als eigenständige Apps auszuführen, musst du zuerst alle definierten Services und alle Ressourcen identifizieren, die jeder einzelne Service verwendet, wie Volumes, Netzwerke und Umgebungseinstellungen. Beginne damit, diese Ressourcen einzeln zu erstellen, und sobald alles eingerichtet ist, leite docker build ...
und docker run ...
-Befehle für jeden Service ab.
Wenn du in der Cloud deployest und eine Plattform wie Sliplane verwendest, reicht es normalerweise aus, einfach die Konfiguration für jeden Service bereitzustellen.
Schauen wir uns den Prozess genauer an.
Grundlegende Docker-Konzepte
Bevor wir beginnen, solltest du die wichtigsten Docker-Konzepte verstehen. Wenn du gerade mit Docker anfängst, empfehle ich dir, die offizielle Dokumentation im Docker Getting Started Guide durchzugehen. Versuche besonders zu verstehen:
- Images
- Container
- Port-Mapping
- Datenpersistenz in Volumes
- Multi-Container-Setups und Netzwerke und
- Container-Konfiguration mit Umgebungsvariablen
Docker ist natürlich viel mehr als das, aber wenn du diese Grundkonzepte verstehst, wird es viel einfacher, Docker Compose-Dateien zu lesen und zu verstehen, und du wirst die meisten Setups zum Laufen bringen können!
Wie man Services aus einer docker-compose.yml-Datei einzeln ausführt
Schauen wir uns ein Beispiel für eine Docker Compose-Datei an, versuchen wir, sie zu dekonstruieren und das Setup als einzelne Container auszuführen:
version: "3.9" # Version von Docker Compose
services: # Definition der Services (Container) für deine App
app: # Service-Name: app
image: my-app:latest # Das Image für den App-Service (neueste Version)
container_name: my_app_container # Benutzerdefinierter Name für den Container
build:
context: ./app # Der Build-Kontext (Verzeichnis für das Dockerfile)
dockerfile: Dockerfile # Das Dockerfile zum Erstellen des Images
args:
- APP_ENV=production # Build-Argument zum Setzen der Umgebungsvariable
environment:
- APP_ENV=production # Umgebungsvariable im Container setzen
- APP_SECRET=mysecret # Weitere Umgebungsvariable für die App
ports:
- "8080:80" # Port 8080 auf dem Host zu Port 80 im Container mappen
volumes:
- app-data:/data # Volume-Mount für persistente App-Daten
networks:
- shared-network # App mit einem gemeinsamen Netzwerk verbinden
depends_on:
- db # Sicherstellen, dass der DB-Service vor dem App-Service startet
restart_policy:
condition: on-failure # App neu starten, wenn sie fehlschlägt
labels:
com.example.description: "My web app" # Benutzerdefiniertes Label zur Beschreibung der App
db: # Service-Name: db
image: postgres:16 # Offizielles PostgreSQL 16-Image verwenden
container_name: my_db_container # Benutzerdefinierter Name für den Datenbank-Container
environment:
POSTGRES_PASSWORD: password # PostgreSQL-Passwort setzen
volumes:
- db-data:/var/lib/postgresql/data # Volume-Mount für Datenbank-Datenpersistenz
networks:
- shared-network # DB mit dem gemeinsamen Netzwerk verbinden
ports:
- "5432:5432" # PostgreSQL-Standardport 5432 vom Container zum Host mappen
volumes:
app-data: # Benanntes Volume für App-Datenpersistenz
db-data: # Benanntes Volume für Datenbank-Datenpersistenz
networks:
shared-network: # Ein gemeinsames Netzwerk für die Kommunikation beider Services definieren
Die Struktur von Docker Compose-Dateien wird in der offiziellen Compose-Dateireferenz beschrieben. In diesem Beispiel gibt es 4 Optionen auf oberster Ebene:
version
services
volumes
undnetworks
.
version
beschreibt nur die verwendete Version von Docker Compose, die wir in diesem Tutorial nicht benötigen.
Die zweite Option, services
, ist hier am wichtigsten. Sie beschreibt die Konfiguration für jeden Container. In der obigen Compose-Datei gibt es 2 Services: app
und db
, die jeweils als Schlüssel innerhalb des services
-Blocks dargestellt werden.
Bevor wir jedoch jeden Service einzeln ausführen können, müssen wir einige Vorbereitungen treffen.
Du kannst sehen, dass beide Service-Blöcke einen volumes
- und networks
-Abschnitt enthalten. Der app
-Service verwendet beispielsweise ein Volume app-data
, das nach /data
gemountet wird, und ein Netzwerk namens shared-network
. Der db
-Service verwendet ein Volume namens db-data
, das nach /var/lib/postgresql/data
gemountet wird.
Alle Volumes und Netzwerke, auf die Services zugreifen können, werden in Block 3 und 4 der Compose-Datei beschrieben. Bevor wir unsere Container ausführen können, müssen wir die beiden Volumes app-data
, db-data
und unser Netzwerk shared-network
einrichten.
# Gemeinsames Netzwerk erstellen, das zur Verbindung der Container verwendet wird
docker network create shared-network
# Volumes für Container erstellen, um Daten zu persistieren
docker volume create app-data
docker volume create db-data
Jetzt, da alles eingerichtet ist, erstellen wir einen Run-Befehl für den ersten Container. In der Compose-Datei siehst du, dass app
von db
abhängt (depends_on
), was bedeutet, dass wir zuerst den db
-Container ausführen müssen:
docker run \
-e POSTGRES_PASSWORD=password \ # environment wird zu -e Flags oder --env-file
-v db-data:/var/lib/postgresql/data \ # db-data Volume mounten
--network shared-network \ # Container mit dem gemeinsamen Netzwerk verbinden
-p 5432:5432 \ # Host-Port 5432 auf Container-Port 5432 mappen
-d \ # im Detached-Modus ausführen
postgres
Beachte, dass ich absichtlich nicht alle Einstellungen verwendet habe, die in der obigen docker-compose.yml
-Datei beschrieben sind. In diesem Fall habe ich einfach die Option container_name
übersprungen. Es wäre möglich, das Flag --name my_db_container
zu verwenden, um den Container zu taggen. Ich wollte jedoch zeigen, dass Docker Compose-Setups oft ausgeführt werden können, ohne jede Option zu kopieren. Es ist wichtig, erforderliche Einstellungen von optionalen zu unterscheiden, und je nach Anwendungsfall kannst du möglicherweise auch eine einfachere Version des Compose-Setups ausführen, die für deinen Anwendungsfall ausreicht.
Gleichzeitig habe ich dem Run-Befehl ein neues Flag -d
hinzugefügt, das in der Compose-Datei nicht explizit beschrieben ist. Die individuelle Ausführung von Containern gibt dir einige Flexibilität. Du könntest beispielsweise auch Umgebungsvariablen in einer .env
-Datei definieren und das Flag --env-file
in deinem Run-Befehl verwenden, um darauf zuzugreifen.
Schauen wir uns als nächstes den app
-Service an. Der Service enthält einen build
-Block in der Compose-Datei. Das bedeutet, dass wir möglicherweise zuerst unser Image erstellen müssen, bevor wir einen Container davon ausführen können.
docker build \
--build-arg APP_ENV=production \ # Build-Zeit-Konfiguration
-t app \ # Image taggen
./app \ # Build-Kontext definieren (Ort, der als Root für nachfolgende Docker-Befehle dient)
Wenn dein Build erfolgreich war, kannst du das App-Image ausführen mit:
docker run -d \
--name my_app_container \ # Benutzerdefinierter Container-Name
-p 8080:80 \ # Port-Mapping
-e APP_ENV=production \ # Umgebungsvariable
-e APP_SECRET=mysecret \ # Weitere Umgebungsvariable
-v app-data:/data \ # Volume-Mount für persistente Daten
--network shared-network \ # Mit gemeinsamen Netzwerk verbinden
--restart on-failure \ # Neustart-Richtlinie
--label com.example.description="My web app" \ # Benutzerdefiniertes Label
my-app:latest
Auch hier könntest du diese App mit einer anderen Neustart-Richtlinie oder zum Beispiel ohne das Label zum Laufen bringen.
Die wichtigsten Einstellungen, die du berücksichtigen solltest, wenn du versuchst, ein Compose-Setup zum Laufen zu bringen, sind:
- Port-Mappings
- Volume-Mounts
- Netzwerke und
- Umgebungsvariablen
Andere Einstellungen sind möglich, aber oft nicht unbedingt erforderlich.
Zusammenfassung
Das Dekonstruieren einer Docker Compose-Datei und das Ausführen von Containern einzeln erfordert die Identifizierung der Services, Netzwerke, Volumes und Umgebungseinstellungen, die in der Compose-Datei definiert sind.
Nachdem du diese Docker-Objekte eingerichtet hast, kannst du die notwendigen Docker Build- und Run-Befehle für jeden Service ableiten.
Während einige Optionen weggelassen werden können, sind Schlüsselelemente wie Port-Mappings, Volume-Mounts und Umgebungsvariablen entscheidend, um das Compose-Setup zu replizieren.
Schau dir Sliplane für eine einfache Möglichkeit an, Docker-Container zu deployen.