"Ich habe den Container aktualisiert – und jetzt sind alle Daten weg." Dieser Satz fällt in Selfhosting-Foren fast täglich. Die Ursache ist fast immer dieselbe: Die Daten lagen im Container statt außerhalb. Wer das Prinzip einmal verstanden hat, verliert nie wieder Daten durch Docker.

Das Grundprinzip: Container sind Wegwerfware

Ein Container ist wie ein frisch installiertes Programm aus einer Vorlage (dem Image). Bei jedem Update wird der alte Container gelöscht und aus dem neuen Image ein neuer gebaut. Alles, was im Container selbst gespeichert war, verschwindet dabei.

Deshalb gilt: Alle wichtigen Daten gehören in ein Volume – einen Speicherort außerhalb des Containers, der beim Neubau einfach wieder eingehängt wird.

Die drei Speicherorte

Wo liegen die Daten? Überlebt Update? Leicht zu sichern?
Im Container (kein Volume) im Container-Dateisystem nein nein
Bind Mount in einem Ordner deiner Wahl, z. B. ./data ja sehr leicht
Named Volume von Docker verwaltet unter /var/lib/docker/volumes/ ja etwas umständlicher

Bind Mounts – unsere Empfehlung für Einsteiger:innen

services:
  app:
    image: beispiel/app
    volumes:
      - ./data:/data

Links vom Doppelpunkt steht der Ordner auf deinem Server (hier data neben der docker-compose.yml), rechts der Pfad im Container. Du siehst die Dateien direkt, kannst sie kopieren und sichern – alles liegt zusammen im App-Ordner.

Named Volumes

services:
  db:
    image: postgres:16
    volumes:
      - dbdaten:/var/lib/postgresql/data

volumes:
  dbdaten:

Docker verwaltet den Speicherort selbst. Das ist sauber und wird in vielen offiziellen Anleitungen genutzt. Anzeigen lassen sich die Volumes mit:

docker volume ls
docker volume inspect projektname_dbdaten

Woher weiß ich, welchen Pfad ich einbinden muss?

Die Dokumentation jedes Images nennt, wo die Anwendung ihre Daten ablegt (z. B. /data, /config, /var/lib/mysql). Genau diesen Pfad musst du einbinden. Bindest du einen falschen Pfad ein, läuft alles scheinbar – bis zum ersten Update.

Prüfen, was ein laufender Container tatsächlich eingebunden hat:

docker inspect CONTAINERNAME --format '{{ json .Mounts }}'

Diese Befehle können Daten löschen

Befehl Was passiert
docker compose down Container weg, Volumes bleiben – harmlos
docker compose down -v löscht auch die Named Volumes – Vorsicht!
docker volume prune löscht alle Volumes, die gerade kein Container nutzt
docker system prune --volumes räumt radikal auf, inklusive ungenutzter Volumes
rm -rf ./data löscht den Bind-Mount-Ordner – wie jeder andere Ordner

Bind Mounts werden von Docker-Befehlen nie gelöscht – ein weiterer Grund, warum wir sie für den Einstieg empfehlen.

Der zweite Klassiker: "Permission denied"

Bei Bind Mounts läuft das Programm im Container oft unter einer bestimmten Benutzer-ID (z. B. 1000). Gehört der Ordner auf dem Server jemand anderem, darf die Anwendung nicht schreiben.

  • Viele Images (z. B. von linuxserver.io) bieten die Variablen PUID und PGID an – setze sie auf deine eigene ID, die du mit id herausfindest.
  • Sonst den Ordner passend übergeben: sudo chown -R 1000:1000 ./data (die richtige ID steht in der Doku des Images).

Backups

  • Bind Mounts: den App-Ordner sichern, am besten bei gestopptem Container (docker compose stop), damit keine halb geschriebenen Dateien im Backup landen.
  • Datenbanken: zusätzlich einen Export anlegen (z. B. pg_dump bzw. mysqldump) – das ist robuster als das rohe Datenverzeichnis.
  • Am einfachsten: Läuft Docker in einer Proxmox-VM, sichern die Proxmox-Backups die komplette VM samt aller Volumes.

Die drei Regeln zum Merken

  1. Jede Anwendung bekommt ein Volume für ihre Daten – vor dem ersten Start.
  2. Nach der Einrichtung einmal testen: Container mit docker compose down && docker compose up -d neu bauen – sind die Daten noch da?
  3. Kein -v bei docker compose down, wenn du nicht genau weißt, warum.

Mehr zu Docker: Docker und Docker Compose installieren.