Daten zwischen Containern teilen - Volumes und Netzwerk richtig einsetzen
Daten zwischen Containern teilen - Volumes und Netzwerk richtig einsetzen
Zwei Container müssen manchmal dieselben Daten nutzen – der richtige Ansatz hängt davon ab ob es um Dateien oder um Live-Kommunikation geht.
Zwei Arten des Teilens
Volumes – für Dateien, die von mehreren Containern gelesen oder geschrieben werden sollen (Uploads, Logs, Konfigs).
Netzwerk – für Live-Kommunikation zwischen Diensten (App → Datenbank, App → Cache).
Beide Konzepte nicht verwechseln: Eine Datenbank teilt man nicht über ein Volume, sondern über das Netzwerk.
Volumes zwischen Containern teilen
services:
app:
image: myapp
volumes:
- uploads:/app/uploads
nginx:
image: nginx:alpine
volumes:
- uploads:/var/www/uploads:ro # Nginx liest nur
volumes:
uploads:
Beide Container greifen auf dasselbe uploads-Volume zu. nginx mountet es read-only (:ro), weil es nur servieren, nicht schreiben soll.
Das Sidecar-Pattern
Ein Sidecar-Container ist ein Hilfscontainer der dasselbe Volume wie der Haupt-Container nutzt und eine unterstützende Aufgabe übernimmt:
services:
app:
image: myapp
volumes:
- logs:/app/logs
log-shipper:
image: fluent/fluent-bit
volumes:
- logs:/var/log/app:ro # Liest Logs des App-Containers
depends_on:
- app
volumes:
logs:
- Weitere Sidecar-Beispiele:
- App schreibt Dateien → Sidecar komprimiert und überträgt
- App generiert Berichte → Sidecar sendet sie per E-Mail
- App loggt → Sidecar leitet zu Loki weiter
Datenbanken niemals per Volume teilen
Datenbanken über ein geteiltes Volume anzubinden ist ein häufiger Fehler:
# FALSCH – nicht so machen
services:
app1:
volumes:
- dbdata:/var/lib/mysql # Beide schreiben gleichzeitig
app2:
volumes:
- dbdata:/var/lib/mysql # Datei-Locks, Corruption garantiert
Stattdessen: eine Datenbankinstanz, beide Apps verbinden sich über das Netzwerk:
services:
db:
image: mysql:8.0
volumes:
- dbdata:/var/lib/mysql
app1:
image: myapp1
environment:
DB_HOST: db
app2:
image: myapp2
environment:
DB_HOST: db
volumes:
dbdata:
Read-only Volumes
Wenn ein Container Daten nur lesen, nicht schreiben darf:
services:
worker:
image: myworker
volumes:
- configs:/etc/myapp:ro # Konfiguration schreibgeschützt
- shared-data:/data:ro # Daten nur lesen
Das :ro-Flag verhindert versehentliche Schreibzugriffe und macht die Intention explizit.
Volumes von einem anderen Container erben
volumes_from (veraltet, aber noch funktional) bindet alle Volumes eines anderen Containers ein:
services:
data:
image: alpine
volumes:
- myvolume:/data
app:
image: myapp
volumes_from:
- data # Übernimmt alle Volumes von 'data'
Lieber explizit benannte Volumes nutzen – das ist klarer und weniger fehleranfällig als volumes_from.