Skip to content

Instantly share code, notes, and snippets.

@apfohl
Created November 13, 2025 09:41
Show Gist options
  • Select an option

  • Save apfohl/a7e3735dba5e425ee8c76e1cc225891c to your computer and use it in GitHub Desktop.

Select an option

Save apfohl/a7e3735dba5e425ee8c76e1cc225891c to your computer and use it in GitHub Desktop.
Docker Stack Migration - Schritt-für-Schritt Anleitung

Vorbereitung auf dem alten Host

Beispiel docker-compose.yml

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:

Schritt 1: Verzeichnisstruktur identifizieren

# Navigiere zu deinem Projekt-Verzeichnis
cd /pfad/zu/deinem/projekt

# Zeige die Struktur an
tree -L 2
# oder falls tree nicht installiert ist:
ls -la

Deine Struktur sollte ungefähr so aussehen:

.
├── docker-compose.yml
├── config/
│   └── nginx.conf
└── html/
    └── (deine Webseiten-Dateien)

Schritt 2: Container stoppen (WICHTIG!)

# Stoppe den Stack, damit keine Daten mehr geschrieben werden
docker compose down

Hinweis: Verwende NICHT docker compose down -v, da dies die Volumes löschen würde!

Schritt 3: Volume-Daten sichern

# 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

Schritt 4: Alle Projektdateien zusammenstellen

# 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.yml
  • config/nginx.conf
  • html/ Verzeichnis mit allen Dateien
  • database_backup.tar.gz

Schritt 5: Paket komprimieren und Checksumme erstellen

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

Transfer zum neuen Host

Schritt 6: Dateien übertragen

# 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/

Installation auf dem neuen Host

Schritt 7: Voraussetzungen prüfen

# 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!

Schritt 8: Transfer überprüfen

cd /tmp

# Checksumme überprüfen
sha256sum -c migration_paket.tar.gz.sha256

Erwartete Ausgabe: migration_paket.tar.gz: OK

Schritt 9: Dateien entpacken

# 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

Schritt 10: Docker Volume erstellen und Daten wiederherstellen

# 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 /data

Wichtig: Der Volume-Name muss zum Verzeichnisnamen passen! Wenn dein Verzeichnis anders heißt, wird Docker automatisch einen entsprechenden Präfix verwenden.

Schritt 11: Stack starten

# Starte den Stack
docker compose up -d

# Überprüfe die Logs
docker compose logs -f

Drücke Ctrl+C um die Logs zu beenden.

Schritt 12: Funktionalität testen

# 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"

Schritt 13: Port-Freigabe anpassen (falls nötig)

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

Nachbereitung

Schritt 14: Aufräumen auf altem Host (OPTIONAL - erst nach erfolgreicher Migration!)

# 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

Schritt 15: Aufräumen auf neuem Host

# Lösche temporäre Dateien
rm /tmp/migration_paket.tar.gz*
rm database_backup.tar.gz

Fehlerbehebung

Problem: Volume-Name stimmt nicht überein

Symptom: 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"

Problem: Permission-Fehler bei PostgreSQL

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 /data

Problem: Nginx zeigt 403 Forbidden

Symptom: 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

Checkliste für erfolgreiche Migration

  • Alter Stack wurde mit docker compose down gestoppt (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 ps zeigt "Up")
  • Webserver ist erreichbar
  • Datenbank enthält die erwarteten Daten
  • Logs zeigen keine Fehler

Wichtige Hinweise

  1. Backup vor dem Löschen: Lösche niemals die alten Daten, bevor du sicher bist, dass alles auf dem neuen Host funktioniert!

  2. Datensicherheit: Wenn du das Backup über ein unsicheres Netzwerk überträgst, verwende SCP/SFTP statt HTTP/FTP.

  3. 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.

  4. PostgreSQL-Versionen: Da du postgres:17-alpine verwendest, stelle sicher, dass auf dem neuen Host die gleiche oder eine kompatible Version läuft.

  5. Netzwerk-Isolation: Die Konfiguration 127.0.0.1:9000:80/tcp bedeutet, dass der Webserver nur lokal auf dem Host erreichbar ist. Plane entsprechend, wenn du externe Zugriffe benötigst.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment