Datenbank-Container im Produktivbetrieb - was man wissen muss
Datenbank-Container im Produktivbetrieb - was man wissen muss
Datenbanken in Docker zu betreiben ist absolut möglich — aber nur, wenn man ein paar wichtige Punkte beachtet.
Das wichtigste zuerst: Persistenz
Ohne Volume verliert ein Datenbankcontainer bei jedem Neustart alle Daten. Benannte Volumes sind der richtige Weg:
services:
postgres:
image: postgres:15
volumes:
- postgres-data:/var/lib/postgresql/data # benanntes Volume
volumes:
postgres-data:
Kein Bind-Mount für Datenbank-Daten — außer du weißt genau, was du tust. Bind-Mounts haben Berechtigungsprobleme und sind schwerer zu sichern.
Version pinnen
# Falsch — lädt irgendwann ein Breaking Update:
image: postgres:latest
# Richtig — kontrollierter Update-Prozess:
image: postgres:15.4
Datenbankversionen haben Migrationspfade. Ein unkontrolliertes Major-Update kann Daten beschädigen.
Port nicht nach außen exposen
Datenbanken gehören ins interne Netzwerk, nicht ins Internet:
services:
postgres:
image: postgres:15
# KEIN ports: mapping!
networks:
- internal
app:
image: myapp
networks:
- internal
- external
networks:
internal:
internal: true # kein Zugang von außen
external:
Ressourcen begrenzen
services:
postgres:
image: postgres:15
deploy:
resources:
limits:
memory: 2g
cpus: "2.0"
Eine unkontrollierte Datenbank kann den gesamten Host-Speicher auffressen und andere Container killen.
Healthcheck
services:
postgres:
image: postgres:15
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
Mit Healthcheck weiß Docker, wann die Datenbank wirklich bereit ist. Abhängige Container warten mit depends_on: condition: service_healthy.
Nicht als root betreiben
PostgreSQL und MySQL-Images laufen standardmäßig als eigener User. Nicht überschreiben:
# Nicht tun:
user: root
Backup-Strategie
# PostgreSQL — Dump
docker exec postgres pg_dump -U postgres mydb > backup_$(date +%Y%m%d).sql
# MySQL — Dump
docker exec mysql mysqldump -u root -p$MYSQL_ROOT_PASSWORD mydb > backup_$(date +%Y%m%d).sql
# Volume-Backup (während Container läuft — für crash-consistent backup vorher stoppen)
docker run --rm \
--volumes-from postgres \
-v $(pwd)/backups:/backup \
alpine tar czf /backup/postgres-data.tar.gz /var/lib/postgresql/data
Restore regelmäßig testen. Ein Backup das sich nicht restoren lässt, ist kein Backup.
PostgreSQL-Tuning über Umgebungsvariablen
environment:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: securepassword
POSTGRES_DB: mydb
# Shared Buffers (empfohlen: 25% RAM)
POSTGRES_SHARED_BUFFERS: 256MB
Für tieferes Tuning: postgresql.conf als Config-Volume einbinden.
Checkliste Produktion
- [ ] Benanntes Volume für Daten
- [ ] Fixe Image-Version (kein
latest) - [ ] Kein Port nach außen
- [ ] Memory-Limit gesetzt
- [ ] Healthcheck konfiguriert
- [ ] Backup-Job läuft und wird getestet
- [ ]
restart: unless-stopped
Zusammenfassung
Datenbanken in Docker sind produktionsreif — wenn Volume, Version, Netzwerk-Isolation, Ressourcen und Backup stimmen. Der häufigste Fehler: kein Backup-Test. Der zweit-häufigste: Port nach außen offen.