Warum ein Container beim Neustart seine Daten verliert

Schreiben Sie eine Zeile in eine Datenbank, die in einem Docker-Container läuft, stoppen Sie den Container und starten Sie ihn neu: Die Zeile ist weg.

Jeder Container bekommt sein Dateisystem bei jedem Start frisch aus seinem Image. Alles, was der Container selbst schreibt – Datenbankdateien, Uploads, Logs –, landet in einer beschreibbaren Schicht, die verworfen wird, sobald der Container entfernt wird. Ein Docker-Volume ist der Weg, diese Daten außerhalb des Containers zu halten, wo sie erhalten bleiben.

Was ist ein Docker-Volume?

Ein Docker-Volume ist ein Mechanismus zum Speichern von Daten außerhalb des Containers, sodass sie auch dann bestehen bleiben, wenn der Container gestoppt, neu gestartet oder gelöscht wird.

Denken Sie an Volumes wie an eine externe Festplatte, die Sie an Ihren Container anschließen. Die Daten werden auf diese “externe Festplatte” geschrieben und bleiben sicher, unabhängig davon, was mit dem Container passiert.

Warum Volumes verwenden?

  • Persistenz: Die Daten überleben den Lebenszyklus des Containers
  • Teilen: Mehrere Container können auf dieselben Daten zugreifen
  • Backup: Es ist einfacher, Datensicherungen zu erstellen
  • Leistung: Volumes sind für I/O-Operationen optimiert
  • Portabilität: Sie können Daten zwischen verschiedenen Hosts verschieben

Volumes, Bind Mounts und tmpfs: was wann

Es gibt drei Wege, Daten dauerhaft zu speichern, in der Reihenfolge, in der Sie dazu greifen sollten: Volumes, Bind Mounts, tmpfs.

1. Volumes - die empfohlene Wahl

Volumes werden vollständig von Docker verwaltet und in einem speziellen Verzeichnis auf dem Host gespeichert (/var/lib/docker/volumes/ unter Linux).

1
2
3
4
5
# Ein Volume erstellen
docker volume create mein-volume

# Das Volume in einem Container verwenden
docker run -v mein-volume:/app/data mein-image

Vorteile:

  • Von Docker verwaltet (einfach zu erstellen, löschen, inspizieren)
  • Funktionieren unter Linux, Windows und Mac
  • Können zwischen mehreren Containern geteilt werden
  • Unterstützen Treiber für Remote-Speicher (Cloud, NFS usw.)

2. Bind Mounts - direkte Verbindung

Bind Mounts verbinden einen bestimmten Ordner auf Ihrem Computer direkt mit dem Container.

1
2
# Einen lokalen Ordner mit dem Container verbinden
docker run -v /pfad/auf/ihrem/pc:/app/data mein-image

Wann sie verwendet werden sollten:

  • Während der Entwicklung, um Codeänderungen in Echtzeit zu sehen
  • Wenn Sie auf bestimmte Dateien des Host-Systems zugreifen müssen
  • Um Konfigurationen zwischen Host und Container zu teilen

Achtung: Bind Mounts hängen von der Dateisystemstruktur des Hosts ab und sind daher weniger portabel.

3. tmpfs Mounts - temporäre Daten im Speicher

tmpfs Mounts speichern Daten im RAM des Hosts, nicht auf der Festplatte.

1
docker run --tmpfs /app/temp mein-image

Wann sie verwendet werden sollten:

  • Für sensible Daten, die nicht auf die Festplatte geschrieben werden sollen
  • Für temporäre Hochleistungs-Caches
  • Die Daten gehen verloren, wenn der Container stoppt (und genau das wollen Sie)

Docker-Volume-Befehle: create, list, inspect, remove

Ein Volume erstellen

1
docker volume create volume-name

Volumes auflisten

1
docker volume ls

Ein Volume inspizieren

1
docker volume inspect volume-name

Dieser Befehl zeigt, wo das Volume physisch gespeichert ist, und andere nützliche Informationen.

Ein Volume löschen

1
2
3
4
5
# Ein bestimmtes Volume löschen
docker volume rm volume-name

# Alle nicht verwendeten Volumes löschen
docker volume prune

Achtung: Das Löschen eines Volumes bedeutet den Verlust aller enthaltenen Daten. Es gibt keinen Papierkorb oder Wiederherstellung.

Docker-Volume-Beispiele: Datenbank, Live-Reload-Entwicklung, Teilen

Beispiel 1: MySQL-Datenbank mit persistenten Daten

Ohne Volume verlieren Sie bei jedem Neustart des MySQL-Containers alle Daten. So lösen Sie das Problem:

1
2
3
4
5
6
7
8
9
# Ein Volume für MySQL-Daten erstellen
docker volume create mysql-data

# MySQL mit dem Volume starten
docker run -d \
  --name mein-mysql \
  -e MYSQL_ROOT_PASSWORD=password123 \
  -v mysql-data:/var/lib/mysql \
  mysql:8

Jetzt können Sie den Container stoppen, neu starten oder sogar löschen und neu erstellen: Die Datenbankdaten bleiben im Volume mysql-data intakt.

Beispiel 2: Webentwicklung mit Bind Mount

Während der Entwicklung möchten Sie, dass Codeänderungen sofort im Container sichtbar sind:

1
2
3
4
5
docker run -d \
  --name meine-seite \
  -p 8080:80 \
  -v $(pwd)/src:/var/www/html \
  php:apache

Jede Änderung an Dateien im Ordner src ist sofort im Container verfügbar.

Beispiel 3: Daten zwischen Containern teilen

Zwei Container, die auf dieselben Dateien zugreifen müssen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Das geteilte Volume erstellen
docker volume create geteilte-daten

# Container, der schreibt
docker run -d --name schreiber -v geteilte-daten:/data alpine \
  sh -c "while true; do date >> /data/log.txt; sleep 5; done"

# Container, der liest
docker run -it --name leser -v geteilte-daten:/data alpine \
  tail -f /data/log.txt

Volumes in Docker Compose

In Docker Compose deklarieren Sie Volumes einmal, und jeder Service, der sie braucht, verweist über den Namen darauf:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
version: '3.8'

services:
  database:
    image: postgres:15
    volumes:
      - postgres-data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: secret

  app:
    image: meine-app
    volumes:
      - ./code:/app           # Bind Mount für Entwicklung
      - logs:/app/logs        # Volume für Logs

volumes:
  postgres-data:    # Von Docker verwaltetes Volume
  logs:             # Von Docker verwaltetes Volume

Mit einem einfachen docker-compose up erstellt Docker automatisch die benötigten Volumes.

Backup und Wiederherstellung von Volumes

Ein Volume sichern

1
2
3
4
docker run --rm \
  -v volume-name:/source:ro \
  -v $(pwd):/backup \
  alpine tar czf /backup/backup.tar.gz -C /source .

Dieser Befehl:

  1. Mountet das Volume im Nur-Lese-Modus (ro)
  2. Erstellt ein komprimiertes Archiv im aktuellen Verzeichnis

Ein Backup wiederherstellen

1
2
3
4
docker run --rm \
  -v volume-name:/target \
  -v $(pwd):/backup \
  alpine tar xzf /backup/backup.tar.gz -C /target

Häufige Fehler, die Sie vermeiden sollten

1. Vergessen, Volumes für Datenbanken zu verwenden

Wenn Sie eine Datenbank in Docker ohne Volume verwenden, verlieren Sie alle Daten. Immer.

2. Bind Mounts in der Produktion verwenden

Bind Mounts sind großartig für die Entwicklung, aber in der Produktion sollten Sie Docker-Volumes für bessere Portabilität und Sicherheit verwenden.

3. Keine Backups der Volumes erstellen

Volumes werden nicht automatisch in Systembackups einbezogen. Planen Sie regelmäßige Backups.

4. Verwaiste Volumes ansammeln

Wenn Sie Container löschen, bleiben die Volumes bestehen. Verwenden Sie regelmäßig:

1
docker volume prune

Um Volumes zu löschen, die nicht mehr mit Containern verbunden sind.

Welche Speicheroption für welchen Zweck

SzenarioLösung
Datenbank in ProduktionDocker-Volume
Lokale EntwicklungBind Mount
Sensible temporäre Datentmpfs
Teilen zwischen ContainernDocker-Volume
KonfigurationsdateienBind Mount oder Volume
Anwendungs-LogsDocker-Volume

Die Regel, die die meisten Fälle abdeckt

Nehmen Sie ein benanntes Volume für alles, was ein Container schreibt und was Sie behalten wollen – Datenbanken zuerst. Nehmen Sie einen Bind Mount, wenn der Container einen Ordner auf Ihrem Rechner so sehen soll, wie Sie ihn gerade bearbeiten, also meist bei der lokalen Entwicklung. tmpfs bleibt für Daten, die nie auf die Festplatte gelangen dürfen.

Sobald eine Datenbank ein Volume hat, können Sie ihren Container so oft löschen und neu erstellen, wie Sie wollen, und die Daten bleiben liegen. Das ist der ganze Sinn.

Verwandte Artikel