Zum Hauptinhalt springen
Zurück zur Kategorie

Docker Compose Leitfaden: Verwaltung von Multi-Container-Anwendungen

Multi-Container-Anwendungen mit Docker Compose definieren und verwalten: Service-Abhängigkeiten, Umgebungsvariablen, Health Checks, Skalierung und Production-Deployment. Umfassender Leitfaden.

Lesezeit: 16 Min DevOps & Automatisierung
docker-composedockercontaineryamldevopsmicroservicedeployment

Inhaltsverzeichnis

Docker Compose Leitfaden: Verwaltung von Multi-Container-Anwendungen

Docker Compose ist ein Tool, mit dem Sie mehrere Docker-Container über eine einzige YAML-Datei definieren und verwalten können. Es ist unverzichtbar für Microservice-Architekturen, Webanwendungen und Entwicklungsumgebungen.

Was ist Docker Compose?

Mit Docker Compose können Sie:

  • Mehrere Services in einer einzigen docker-compose.yml-Datei definieren
  • Abhängigkeiten zwischen Services verwalten
  • Netzwerk- und Volume-Konfigurationen zentral verwalten
  • Den gesamten Stack mit einem einzigen Befehl starten/stoppen

Docker Compose v2 läuft mit dem Befehl docker compose (ohne Bindestrich) und ist in die Docker CLI integriert. Der ältere Befehl docker-compose wird weiterhin unterstützt.

Grundlegende docker-compose.yml Struktur

hljs yaml
version: '3.9'

services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro
    restart: unless-stopped

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: geheimes_passwort
      MYSQL_DATABASE: meine_app
    volumes:
      - db_data:/var/lib/mysql
    restart: unless-stopped

volumes:
  db_data:

Services, Volumes und Networks

Services definieren

hljs yaml
services:
  app:
    build:
      context: ./app
      dockerfile: Dockerfile
    image: meine-app:latest
    container_name: app-container
    ports:
      - "3000:3000"
    environment:
      NODE_ENV: production
      DB_HOST: datenbank
    depends_on:
      datenbank:
        condition: service_healthy
    networks:
      - app-netzwerk
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

Volumes definieren

hljs yaml
volumes:
  # Named Volume (von Docker verwaltet)
  db_data:
    driver: local

  # Externes Volume (bereits erstellt)
  vorhandenes_volume:
    external: true

  # Benutzerdefinierte Treiberoptionen
  nfs_volume:
    driver: local
    driver_opts:
      type: nfs
      o: addr=192.168.1.100,rw
      device: ":/nfs/freigabe"

Networks definieren

hljs yaml
networks:
  # Standard-Bridge-Netzwerk
  app-netzwerk:
    driver: bridge

  # Mit benutzerdefiniertem Subnetz
  benutzerdefiniertes-netz:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16

  # Externes Netzwerk
  vorhandenes-netz:
    external: true

depends_on und Healthcheck

Kontrollieren Sie die Startreihenfolge der Services mit depends_on:

hljs yaml
services:
  web:
    image: nginx:alpine
    depends_on:
      api:
        condition: service_healthy
      db:
        condition: service_healthy

  api:
    build: ./api
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: passwort
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

depends_on kontrolliert nur die Startreihenfolge. Ohne condition: service_healthy können Sie nicht garantieren, dass der Service bereit ist.

Umgebungsvariablen und env_file

Direkte Definition

hljs yaml
services:
  app:
    image: meine-app:latest
    environment:
      - NODE_ENV=production
      - PORT=3000
      - DB_HOST=datenbank
      - DB_PORT=5432

.env-Datei verwenden

hljs yaml
services:
  app:
    image: meine-app:latest
    env_file:
      - .env
      - .env.production

.env-Datei:

hljs bash
# .env
NODE_ENV=production
DB_HOST=datenbank
DB_PORT=5432
DB_NAME=meine_app
DB_USER=benutzer
DB_PASS=geheimes_passwort
JWT_SECRET=sehr_geheimer_schluessel
REDIS_URL=redis://redis:6379

Fügen Sie .env zu .gitignore hinzu. Committen Sie niemals sensible Informationen in Git.

Skalierung (--scale)

Sie können Services mit Docker Compose horizontal skalieren:

hljs bash
# api-Service mit 3 Instanzen starten
docker compose up -d --scale api=3

# Anzahl der laufenden Instanzen ändern
docker compose up -d --scale api=5

# Bestimmten Service skalieren
docker compose scale api=3 worker=2

Load-Balancer-Konfiguration für Skalierung:

hljs yaml
services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - api

  api:
    build: ./api
    # Keine Ports definieren - nginx leitet weiter
    expose:
      - "3000"
    environment:
      NODE_ENV: production

Override-Dateien

Verwenden Sie Override-Dateien für verschiedene Umgebungen:

hljs yaml
# docker-compose.override.yml (Entwicklung)
services:
  app:
    build:
      context: .
      target: development
    volumes:
      - .:/app
      - /app/node_modules
    environment:
      NODE_ENV: development
    command: npm run dev

  db:
    ports:
      - "5432:5432"  # In der Entwicklung nach außen öffnen
hljs yaml
# docker-compose.prod.yml (Production)
services:
  app:
    image: registry.example.com/meine-app:latest
    restart: always
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '1.0'
          memory: 1G

Verwendung:

hljs bash
# Entwicklung (Override wird automatisch angewendet)
docker compose up -d

# Production
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Production Best Practices

Vollständiges Production-Beispiel

hljs yaml
version: '3.9'

services:
  nginx:
    image: nginx:1.25-alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - certbot_data:/etc/letsencrypt:ro
    depends_on:
      - api
    restart: always
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  api:
    image: registry.example.com/api:${APP_VERSION:-latest}
    env_file: .env.production
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    restart: always
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M

  db:
    image: postgres:15-alpine
    env_file: .env.production
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: always
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres}"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    command: redis-server --requirepass ${REDIS_PASSWORD} --maxmemory 256mb --maxmemory-policy allkeys-lru
    volumes:
      - redis_data:/data
    restart: always
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3

volumes:
  postgres_data:
  redis_data:
  certbot_data:

Wichtige Befehle

hljs bash
# Alle Services starten
docker compose up -d

# Bestimmten Service starten
docker compose up -d api

# Logs verfolgen
docker compose logs -f
docker compose logs -f api

# Services stoppen
docker compose down

# Services stoppen und Volumes löschen
docker compose down -v

# Service neu starten
docker compose restart api

# Service-Status anzeigen
docker compose ps

# Befehl in Service ausführen
docker compose exec api bash

# Images neu erstellen
docker compose build --no-cache
docker compose up -d --build

# Konfiguration validieren
docker compose config

Fazit

Docker Compose ist der praktischste Weg, Multi-Container-Anwendungen zu verwalten. Es bietet eine konsistente Umgebung von der Entwicklung bis zur Production. Mit Override-Dateien können Sie verschiedene Umgebungen flexibel konfigurieren, und mit Healthcheck und depends_on können Sie Service-Abhängigkeiten sicher verwalten.