Container sind flüchtig - beim Löschen verschwinden alle Daten. Docker-Volumes lösen dieses Problem und ermöglichen persistente Datenspeicherung.
Warum Volumes?
Ohne Volumes gehen Daten verloren bei:
- Container-Neuerstellung
- Image-Updates
docker rm
Mit Volumes bleiben Daten erhalten:
- Datenbanken
- Uploads
- Konfigurationen
- Logs
Arten der Datenspeicherung
1. Volumes (empfohlen)
Von Docker verwaltet, in /var/lib/docker/volumes/:
docker volume create mein-volume
docker run -v mein-volume:/app/data nginx2. Bind Mounts
Host-Verzeichnis direkt einbinden:
docker run -v /host/pfad:/container/pfad nginx3. tmpfs Mounts
Im RAM, nicht persistent:
docker run --tmpfs /app/cache nginxVolumes erstellen und verwalten
Volume erstellen
docker volume create mein-volumeVolumes auflisten
docker volume lsVolume-Details
docker volume inspect mein-volumeVolume löschen
docker volume rm mein-volumeUngenutzte Volumes löschen
docker volume pruneVolumes in Containern nutzen
Mit -v Flag
docker run -d \
--name mysql-db \
-v mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=geheim \
mysql:8Mit --mount (moderner)
docker run -d \
--name mysql-db \
--mount source=mysql-data,target=/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=geheim \
mysql:8Readonly-Volume
docker run -d \
-v config-vol:/etc/config:ro \
nginxBind Mounts
Host-Verzeichnis einbinden
docker run -d \
-v /var/www/html:/usr/share/nginx/html \
nginxMit absolutem Pfad (Pflicht)
# Richtig
docker run -v /home/user/app:/app nginx
# Falsch (wird als Volume-Name interpretiert)
docker run -v ./app:/app nginxFür Entwicklung ideal
docker run -d \
-v $(pwd)/src:/app/src \
-v $(pwd)/config:/app/config \
node:18Docker Compose
Volumes in docker-compose.yml
version: '3.8'
services:
db:
image: mysql:8
volumes:
- mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: geheim
web:
image: wordpress
volumes:
- wp-content:/var/www/html/wp-content
- ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini:ro
depends_on:
- db
volumes:
mysql-data:
wp-content:Benannte vs. anonyme Volumes
volumes:
# Benannt (empfohlen)
mysql-data:
# Mit Optionen
nfs-data:
driver: local
driver_opts:
type: nfs
o: addr=10.0.0.1,rw
device: ":/data"Externe Volumes
volumes:
existing-volume:
external: trueBackup von Volumes
Mit tar
docker run --rm \
-v mysql-data:/data \
-v $(pwd):/backup \
ubuntu tar cvf /backup/mysql-backup.tar /dataDirekt aus Volume-Verzeichnis
# Volume-Pfad finden
docker volume inspect mysql-data --format '{{ .Mountpoint }}'
# Backup erstellen
tar -czvf backup.tar.gz /var/lib/docker/volumes/mysql-data/_dataVolume klonen
docker volume create new-volume
docker run --rm \
-v mysql-data:/from \
-v new-volume:/to \
ubuntu bash -c "cp -av /from/* /to/"Volume-Daten wiederherstellen
docker run --rm \
-v mysql-data:/data \
-v $(pwd):/backup \
ubuntu bash -c "cd /data && tar xvf /backup/mysql-backup.tar --strip 1"Praktische Beispiele
WordPress mit Volumes
version: '3.8'
services:
wordpress:
image: wordpress
ports:
- "80:80"
volumes:
- wp-files:/var/www/html
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_PASSWORD: geheim
db:
image: mysql:8
volumes:
- db-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: geheim
MYSQL_DATABASE: wordpress
volumes:
wp-files:
db-data:Nextcloud mit Volumes
version: '3.8'
services:
nextcloud:
image: nextcloud
volumes:
- nextcloud-data:/var/www/html
- nextcloud-apps:/var/www/html/custom_apps
- nextcloud-config:/var/www/html/config
ports:
- "8080:80"
volumes:
nextcloud-data:
nextcloud-apps:
nextcloud-config:Entwicklungsumgebung
version: '3.8'
services:
app:
build: .
volumes:
# Code live ändern
- ./src:/app/src
# node_modules im Volume (schneller)
- node_modules:/app/node_modules
ports:
- "3000:3000"
volumes:
node_modules:Volume-Treiber
Lokaler Treiber (Standard)
docker volume create --driver local mein-volumeNFS-Volume
docker volume create \
--driver local \
--opt type=nfs \
--opt o=addr=192.168.1.1,rw \
--opt device=:/shared \
nfs-volumeIn Compose
volumes:
nfs-data:
driver: local
driver_opts:
type: nfs
o: addr=192.168.1.1,rw,nfsvers=4
device: ":/shared"tmpfs für temporäre Daten
docker run -d \
--tmpfs /app/cache:size=100m \
nginxIn Compose:
services:
app:
image: nginx
tmpfs:
- /app/cache:size=100mBest Practices
1. Volumes für persistente Daten
volumes:
- db-data:/var/lib/mysql # RichtigNicht:
volumes:
- ./mysql-data:/var/lib/mysql # Bind Mount für Datenbank = Probleme2. Bind Mounts für Entwicklung
volumes:
- ./src:/app/src # Code-Änderungen live3. Separate Volumes für verschiedene Daten
volumes:
- mysql-data:/var/lib/mysql
- mysql-logs:/var/log/mysql
- mysql-conf:/etc/mysql/conf.d4. Backup-Strategie
- Regelmäßige Volume-Backups
- Vor Updates/Upgrades sichern
- Backup-Integrität testen
Troubleshooting
Permission-Probleme
# User-ID im Container prüfen
docker exec container-name id
# Volume mit korrektem User erstellen
docker run --rm \
-v mein-volume:/data \
ubuntu chown -R 1000:1000 /dataVolume nicht beschreibbar
# Prüfen ob :ro gesetzt
docker inspect container-name | grep -A5 Mounts
# Ohne :ro neu starten
docker run -v volume:/data nginxVolume-Daten finden
docker volume inspect volume-name --format '{{ .Mountpoint }}'Fazit
Volumes sind essenziell für produktive Docker-Umgebungen. Nutzen Sie benannte Volumes für Datenbanken und persistente Daten, Bind Mounts für Entwicklung. Regelmäßige Backups nicht vergessen.