Daten nie im Container-Layer speichern - warum und wie
Daten nie im Container-Layer speichern - warum und wie
Wer Daten im Container-Layer statt in Volumes speichert, verliert sie beim nächsten docker compose up – ein Fehler der besonders bei Datenbanken schmerzt.
Was der Container-Layer ist
Jeder Container besteht aus Read-Only-Image-Layern plus einem beschreibbaren Container-Layer oben drauf. Alle Schreiboperationen landen dort. Wird der Container gelöscht (docker rm oder docker compose up mit geänderter Config), ist dieser Layer weg.
# Was hat der Container in seinen Layer geschrieben?
docker diff mycontainer
# Ausgabe:
# A /var/lib/mysql/ibdata1 ← Datenbank schreibt direkt in den Layer
# A /var/log/app/access.log ← Logs landen im Container-Layer
A = Added, C = Changed, D = Deleted.
Der häufigste Fehler: Datenbank ohne Volume
# GEFÄHRLICH – Daten weg beim nächsten docker compose up
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
# Kein volumes:-Block = Daten im Container-Layer
Nach docker compose down && docker compose up ist die Datenbank leer.
# RICHTIG – Daten überleben Container-Neustarts
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
volumes:
- dbdata:/var/lib/mysql
volumes:
dbdata:
Was typisch im Container-Layer landet (und nicht sollte)
/var/lib/mysql/ → Named Volume
/var/lib/postgresql/ → Named Volume
/var/lib/redis/ → Named Volume
/var/www/html/uploads → Named Volume oder Bind Mount
/app/logs/ → Named Volume oder Bind Mount
/home/user/.config/ → Named Volume
Was im Container-Layer bleiben darf
Nicht alles muss persistiert werden. Gute Kandidaten für den Container-Layer:
/tmp/ → Temporäre Verarbeitung, nach Restart sowieso weg
/run/ → PID-Dateien, Sockets
Assets im Image → CSS, JS, Templates – ins Image gebacken ist korrekt
Read-only Assets die sich mit dem Image ändern (z.B. HTML-Templates) gehören ins Image, nicht in ein Volume.
Mit docker diff prüfen
Bevor man ein Produktivsystem deployed:
# Container starten, Anwendung kurz nutzen
docker compose up -d
# Etwas Zeit lassen damit Daten geschrieben werden
# Prüfen was in den Container-Layer geschrieben wurde
docker diff myapp_db_1
Wenn hier Datenbankdateien oder Upload-Ordner auftauchen, fehlen Volumes.
Nachträgliche Volumes hinzufügen
Wenn ein laufender Container Daten im Layer hat und man ein Volume ergänzen will:
# 1. Daten aus dem Container-Layer exportieren
docker run --rm --volumes-from mycontainer -v $(pwd):/backup alpine \
tar czf /backup/rescue.tar.gz /var/lib/mysql
# 2. Neues Volume mit diesen Daten befüllen
docker volume create rescued-data
docker run --rm -v rescued-data:/data -v $(pwd):/backup alpine \
tar xzf /backup/rescue.tar.gz -C /data --strip-components=1
# 3. docker-compose.yml um Volume ergänzen und Container neu erstellen
docker compose up -d