services:
database:
image: postgres:17-alpine
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
volumes:
- database_data:/var/lib/postgresql/data
webserver:
image: nginx:alpine
ports:
- 127.0.0.1:9000:80/tcp
volumes:
- ./config/nginx.conf:/etc/nginx/nginx.conf:ro
- ./html:/usr/share/nginx/html:ro
depends_on:
- database
volumes:
database_data:# Navigiere zu deinem Projekt-Verzeichnis
cd /pfad/zu/deinem/projekt
# Zeige die Struktur an
tree -L 2
# oder falls tree nicht installiert ist:
ls -laDeine Struktur sollte ungefähr so aussehen:
.
├── docker-compose.yml
├── config/
│ └── nginx.conf
└── html/
└── (deine Webseiten-Dateien)
# Stoppe den Stack, damit keine Daten mehr geschrieben werden
docker compose downHinweis: Verwende NICHT docker compose down -v, da dies die Volumes löschen würde!
# Finde den genauen Volume-Namen heraus
docker volume ls | grep database_data
# Der Name ist wahrscheinlich: <verzeichnisname>_database_data
# Beispiel: meinprojekt_database_data
# Erstelle ein Backup des Volumes
docker run --rm \
-v <projektname>_database_data:/source:ro \
-v $(pwd):/backup \
alpine \
tar -czf /backup/database_backup.tar.gz -C /source .Erklärung: Dieser Befehl startet einen temporären Alpine-Container, der:
- Das Database-Volume read-only mountet
- Dein aktuelles Verzeichnis als Backup-Ziel verwendet
- Die gesamten Daten als komprimiertes tar.gz speichert
# Erstelle ein Verzeichnis für die Migration
mkdir -p ~/migration_paket
# Kopiere alle Projektdateien
cp -r . ~/migration_paket/
# Überprüfe, dass alle wichtigen Dateien vorhanden sind
ls -la ~/migration_paket/Dein Migration-Paket sollte enthalten:
docker-compose.ymlconfig/nginx.confhtml/Verzeichnis mit allen Dateiendatabase_backup.tar.gz
cd ~
tar -czf migration_paket.tar.gz migration_paket/
# Erstelle eine Checksumme zur Überprüfung
sha256sum migration_paket.tar.gz > migration_paket.tar.gz.sha256# Methode 1: Mit SCP (von altem Host aus)
scp migration_paket.tar.gz migration_paket.tar.gz.sha256 benutzer@neuer-host:/tmp/
# Methode 2: Mit rsync (mehr Fehlertoleranz)
rsync -avz --progress migration_paket.tar.gz migration_paket.tar.gz.sha256 benutzer@neuer-host:/tmp/# SSH auf den neuen Host
ssh benutzer@neuer-host
# Prüfe Docker Installation
docker --version
docker compose version
# Falls Docker nicht installiert ist, installiere es:
# Für Debian/Ubuntu:
# curl -fsSL https://get.docker.com | sh
# sudo usermod -aG docker $USER
# Logout und Login erforderlich!cd /tmp
# Checksumme überprüfen
sha256sum -c migration_paket.tar.gz.sha256Erwartete Ausgabe: migration_paket.tar.gz: OK
# Wähle ein Zielverzeichnis (Beispiel)
mkdir -p ~/docker-projekte
cd ~/docker-projekte
# Entpacke das Migrations-Paket
tar -xzf /tmp/migration_paket.tar.gz
cd migration_paket# Erstelle zunächst das Volume durch einen Dummy-Befehl
docker volume create migration_paket_database_data
# Stelle die Daten wieder her
docker run --rm \
-v migration_paket_database_data:/target \
-v $(pwd):/backup \
alpine \
sh -c "cd /target && tar -xzf /backup/database_backup.tar.gz"
# Überprüfe, ob Daten vorhanden sind
docker run --rm \
-v migration_paket_database_data:/data \
alpine \
ls -la /dataWichtig: Der Volume-Name muss zum Verzeichnisnamen passen! Wenn dein Verzeichnis anders heißt, wird Docker automatisch einen entsprechenden Präfix verwenden.
# Starte den Stack
docker compose up -d
# Überprüfe die Logs
docker compose logs -fDrücke Ctrl+C um die Logs zu beenden.
# Prüfe, ob Container laufen
docker compose ps
# Teste den Webserver (lokal auf dem neuen Host)
curl http://localhost:9000
# Teste die Datenbank-Verbindung
docker compose exec database psql -U postgres -c "\l"Falls du von außen auf den neuen Host zugreifen möchtest, musst du eventuell die Port-Bindung anpassen:
Original: 127.0.0.1:9000:80/tcp (nur lokal erreichbar)
Optionen:
0.0.0.0:9000:80/tcp- von überall erreichbar (Vorsicht: Sicherheit beachten!)192.168.1.10:9000:80/tcp- nur von bestimmter IP erreichbar
Nachdem du die docker-compose.yml angepasst hast:
docker compose up -d# Auf dem ALTEN Host:
# cd /pfad/zu/deinem/alten/projekt
# docker compose down -v # Löscht auch die Volumes
# cd ..
# rm -rf altes-projekt-verzeichnis# Lösche temporäre Dateien
rm /tmp/migration_paket.tar.gz*
rm database_backup.tar.gzSymptom: Datenbank startet mit leerer Datenbank
Lösung:
# Finde den tatsächlichen Volume-Namen
docker volume ls
# Passe den Restore-Befehl an mit dem korrekten Namen
docker run --rm \
-v TATSÄCHLICHER_VOLUME_NAME:/target \
-v $(pwd):/backup \
alpine \
sh -c "cd /target && tar -xzf /backup/database_backup.tar.gz"Symptom: PostgreSQL startet nicht, Logs zeigen Permission-Fehler
Lösung:
# Korrigiere die Permissions im Volume
docker run --rm \
-v VOLUME_NAME:/data \
alpine \
chown -R 999:999 /dataSymptom: Webserver läuft, aber zeigt keine Inhalte
Lösung:
# Prüfe, ob html-Verzeichnis existiert und Dateien enthält
ls -la html/
# Prüfe die nginx.conf Konfiguration
cat config/nginx.conf- Alter Stack wurde mit
docker compose downgestoppt (NICHT-v!) - Database-Volume wurde gesichert
- Alle Projektdateien (docker-compose.yml, config/, html/) wurden kopiert
- Checksumme wurde auf neuem Host erfolgreich überprüft
- Volume wurde auf neuem Host wiederhergestellt
- Container starten erfolgreich (
docker compose pszeigt "Up") - Webserver ist erreichbar
- Datenbank enthält die erwarteten Daten
- Logs zeigen keine Fehler
-
Backup vor dem Löschen: Lösche niemals die alten Daten, bevor du sicher bist, dass alles auf dem neuen Host funktioniert!
-
Datensicherheit: Wenn du das Backup über ein unsicheres Netzwerk überträgst, verwende SCP/SFTP statt HTTP/FTP.
-
Volume-Namen: Docker Compose verwendet den Verzeichnisnamen als Präfix für Volumes. Achte darauf, dass du das Verzeichnis gleich benennst oder die Volume-Namen entsprechend anpasst.
-
PostgreSQL-Versionen: Da du
postgres:17-alpineverwendest, stelle sicher, dass auf dem neuen Host die gleiche oder eine kompatible Version läuft. -
Netzwerk-Isolation: Die Konfiguration
127.0.0.1:9000:80/tcpbedeutet, dass der Webserver nur lokal auf dem Host erreichbar ist. Plane entsprechend, wenn du externe Zugriffe benötigst.