docker-compose.yml (YAML-Format)Aufbau der Datei
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- api
api:
build: ./api
environment:
- DB_URL=postgres://db/myapp
depends_on:
db:
condition: service_healthy
db:
image: postgres:16
environment:
POSTGRES_DB: myapp
POSTGRES_PASSWORD: secret
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready"]
interval: 5s
timeout: 3s
retries: 5
volumes:
pgdata:
networks:
default:
driver: bridge
Fertiges Image verwenden
services:
db:
image: postgres:16-alpine
# Registry: docker.io (Standard)
# oder: ghcr.io/org/image:tag
cache:
image: redis:7-alpine
Image lokal bauen
services:
api:
build:
context: ./api # Verzeichnis
dockerfile: Dockerfile
args:
- APP_ENV=production
target: runtime # Multi-Stage
Build + Image kombinieren
services:
api:
build: ./api # kurze Form
image: myorg/api:1.0 # Name für Push
# Rebuild erzwingen:
# docker compose build --no-cache
# docker compose up --build
Wichtige Build-Befehle
docker compose build – alle Images bauendocker compose pull – Images aktualisierendocker compose push – Images in Registry pushen--build-Flag bei up: Rebuild vor StartStandard-Netzwerk
bridge-Netzwerkhttp://api:8000Mehrere Netzwerke
services:
nginx:
networks:
- frontend
- backend
api:
networks:
- backend
db:
networks:
- backend
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # kein Internetzugang
Named Volume
services:
db:
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
driver: local
# Daten bleiben bei 'down' erhalten
# 'down -v' entfernt sie
Bind Mount
services:
api:
volumes:
- ./src:/app/src # Dev
- ./config:/etc/config:ro # readonly
tmpfs (RAM-Disk)
services:
api:
tmpfs:
- /tmp
- /run/secrets:size=1m
Volume-Befehle
docker volume ls – alle Volumes anzeigendocker volume inspect pgdata – Detailsdocker compose down -v – Volumes löschendocker volume prune – ungenutzte löschenExternes Volume
volumes:
pgdata:
external: true # vorher angelegt
Variablen definieren
services:
api:
environment:
# direkt
- APP_ENV=production
# aus Shell-Umgebung
- SECRET_KEY
# als Map
DB_HOST: db
DB_PORT: 5432
.env-Datei (Standard)
# .env
DB_PASSWORD=geheim123
API_KEY=abc-xyz
IMAGE_TAG=1.2.0
services:
api:
image: myapp:${IMAGE_TAG}
environment:
- DB_PASSWORD=${DB_PASSWORD}
env_file
services:
api:
env_file:
- .env.base
- .env.local # überschreibt
Secrets (Swarm-kompatibel)
services:
api:
secrets:
- db_password
secrets:
db_password:
file: ./secrets/db_password.txt
# oder: external: true
/run/secrets/ gemountet.env niemals in Git committen → .gitignore.env.example mit Platzhaltern bereitstellenports: Host ↔ Container
services:
web:
ports:
# HOST:CONTAINER
- "80:80"
- "443:443"
# nur localhost
- "127.0.0.1:8080:80"
# zufälliger Host-Port
- "8000"
# UDP
- "5353:5353/udp"
expose: nur intern sichtbar
services:
api:
expose:
- "8000" # nur im Docker-Netz
# kein Host-Port → sicherer
Port-Strategie
Sicherheitsempfehlung
| Service | Ansatz |
|---|---|
| nginx / Proxy | ports: 80, 443 |
| api, worker | expose (intern) |
| db, redis | expose / kein Port |
depends_on-Bedingungen
services:
api:
depends_on:
db:
condition: service_healthy
redis:
condition: service_started # Standard
migrations:
condition: service_completed_successfully
Healthcheck definieren
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL",
"pg_isready -U postgres"]
interval: 5s
timeout: 3s
retries: 5
start_period: 10s
service_started: Container läuft (default)service_healthy: Healthcheck OKservice_completed_successfully: Exit-Code 0Restart-Policies
services:
api:
restart: unless-stopped
# Optionen:
# no – kein Neustart (default)
# always – immer neu starten
# on-failure – nur bei Fehler
# unless-stopped – bis manuell gestoppt
Ressourcen begrenzen
api:
deploy:
resources:
limits:
cpus: "0.50"
memory: 512M
reservations:
cpus: "0.25"
memory: 128M
Replicas (horizontale Skalierung)
api:
deploy:
replicas: 3
# docker compose up --scale api=3
Logging-Konfiguration
api:
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
# Alternativen: syslog, journald,
# fluentd, gelf, awslogs
Empfehlungen
restart: unless-stoppedrestart: no (Fehler direkt sehen)