Docker Compose ermöglicht es, mehrere Container als eine Anwendung zu definieren und zu verwalten. Statt vieler einzelner docker run-Befehle beschreiben Sie alles in einer YAML-Datei.

Was ist Docker Compose?

Docker Compose ist ein Tool zur Definition und Ausführung von Multi-Container-Anwendungen. Typisches Beispiel: Eine Web-App braucht einen Webserver, eine Datenbank und einen Cache - drei Container, die zusammenarbeiten.

Installation

Docker Compose ist in aktuellen Docker-Versionen enthalten (als docker compose).

Prüfen:

docker compose version

Falls nicht vorhanden (ältere Systeme):

apt install docker-compose-plugin

Grundstruktur einer docker-compose.yml

version: "3.8"

services:
  web:
    image: nginx:latest
    ports:
      - "80:80"

  db:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: geheim

Wichtige Befehle

Container starten

# Im Vordergrund
docker compose up

# Im Hintergrund (detached)
docker compose up -d

Container stoppen

# Stoppen
docker compose stop

# Stoppen und entfernen
docker compose down

# Inkl. Volumes löschen
docker compose down -v

Status anzeigen

docker compose ps
docker compose logs
docker compose logs -f web    # Logs eines Services folgen

Neubauen

docker compose build
docker compose up -d --build

Konfigurationsoptionen

Images

services:
  web:
    image: nginx:1.25

Build aus Dockerfile

services:
  app:
    build: .
    # oder detaillierter:
    build:
      context: ./app
      dockerfile: Dockerfile.prod

Ports

services:
  web:
    ports:
      - "80:80"           # Host:Container
      - "443:443"
      - "127.0.0.1:8080:80"  # Nur lokal

Umgebungsvariablen

services:
  db:
    environment:
      MYSQL_ROOT_PASSWORD: geheim
      MYSQL_DATABASE: app
    # oder aus Datei:
    env_file:
      - .env

Volumes

services:
  db:
    volumes:
      - ./data:/var/lib/mysql           # Bind Mount
      - db_data:/var/lib/mysql          # Named Volume

volumes:
  db_data:

Netzwerke

services:
  web:
    networks:
      - frontend
  db:
    networks:
      - backend

networks:
  frontend:
  backend:

Abhängigkeiten

services:
  web:
    depends_on:
      - db
      - redis
  db:
    image: mysql:8
  redis:
    image: redis:alpine

Restart-Policy

services:
  web:
    restart: always      # immer neustarten
    # Optionen: no, always, on-failure, unless-stopped

Ressourcen begrenzen

services:
  web:
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 512M

Praxisbeispiele

WordPress mit MySQL

version: "3.8"

services:
  wordpress:
    image: wordpress:latest
    ports:
      - "80:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress_pw
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wordpress_data:/var/www/html
    depends_on:
      - db
    restart: always

  db:
    image: mysql:8
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress_pw
      MYSQL_ROOT_PASSWORD: root_pw
    volumes:
      - db_data:/var/lib/mysql
    restart: always

volumes:
  wordpress_data:
  db_data:

Nginx + PHP-FPM + MariaDB

version: "3.8"

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./src:/var/www/html
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php

  php:
    image: php:8.2-fpm
    volumes:
      - ./src:/var/www/html

  db:
    image: mariadb:10
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: app
      MYSQL_USER: app
      MYSQL_PASSWORD: app_pw
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

Nextcloud

version: "3.8"

services:
  nextcloud:
    image: nextcloud:latest
    ports:
      - "8080:80"
    environment:
      MYSQL_HOST: db
      MYSQL_DATABASE: nextcloud
      MYSQL_USER: nextcloud
      MYSQL_PASSWORD: nextcloud_pw
    volumes:
      - nextcloud_data:/var/www/html
    depends_on:
      - db
      - redis
    restart: always

  db:
    image: mariadb:10
    environment:
      MYSQL_ROOT_PASSWORD: root_pw
      MYSQL_DATABASE: nextcloud
      MYSQL_USER: nextcloud
      MYSQL_PASSWORD: nextcloud_pw
    volumes:
      - db_data:/var/lib/mysql
    restart: always

  redis:
    image: redis:alpine
    restart: always

volumes:
  nextcloud_data:
  db_data:

Mehrere Compose-Dateien

Entwicklung vs. Produktion

docker-compose.yml (Basis):

version: "3.8"
services:
  web:
    image: myapp:latest

docker-compose.override.yml (Entwicklung, automatisch geladen):

version: "3.8"
services:
  web:
    volumes:
      - ./src:/app
    environment:
      DEBUG: "true"

docker-compose.prod.yml (Produktion):

version: "3.8"
services:
  web:
    restart: always
    environment:
      DEBUG: "false"

Starten:

# Entwicklung (lädt automatisch override)
docker compose up

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

.env-Datei verwenden

.env:

MYSQL_ROOT_PASSWORD=supersecret
MYSQL_DATABASE=myapp

docker-compose.yml:

services:
  db:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}

Nützliche Befehle

# Konfiguration validieren
docker compose config

# Einzelnen Service neustarten
docker compose restart web

# In Container einloggen
docker compose exec web bash

# Einmaligen Befehl ausführen
docker compose run --rm web npm install

# Alte Container aufräumen
docker compose down --rmi local

Best Practices

1. Versionskontrolle: docker-compose.yml gehört ins Git 2. Secrets: Passwörter in .env, die Datei in .gitignore 3. Named Volumes: Für persistente Daten 4. Health Checks: Für Produktionsumgebungen 5. Logging: Zentrales Logging konfigurieren

Fazit

Docker Compose macht Multi-Container-Setups handhabbar. Eine docker-compose.yml dokumentiert die gesamte Infrastruktur und ermöglicht reproduzierbare Deployments. Für Entwicklung und kleine bis mittlere Produktionsumgebungen ist es ideal.