Files

2.4 KiB

Service Migration Prep Workflow

Standard pattern for migrating Docker-based services from one server to another (e.g., from Hetzner to Netcup).

The Sequence

Snapshot VM → Update OS + App in place → Plan clean install → Execute migration → Verify

Phase 1: Discovery

SSH to the current server and collect:

# What's running
docker ps --format '{{.Names}}\t{{.Image}}\t{{.Status}}'

# Where compose lives
find / -maxdepth 4 -name 'docker-compose.yml' 2>/dev/null | grep -v 'node_modules\|overlay2\|diff\|merged'

# Data size
du -sh /home/<service>/data/

# Data location
docker inspect <container> --format '{{range .Mounts}}{{.Source}}{{"\n"}}{{end}}'

Record: hostname, provider, IP, OS version, Docker version, compose path, data size, image versions, port mappings.

Phase 2: Snapshot (provider-level)

Don't attempt a direct data transfer (rsync/script) for services over ~5GB. Use the provider's snapshot mechanism:

  • Hetzner: API creates a full disk snapshot of the running VM (instant, no downtime)
  • Generic fallback: tar czf /tmp/service-backup.tgz -C /home/service/ . then upload to S3

The user explicitly prefers this approach over custom backup scripts.

Phase 3: Update in Place

After snapshot:

  1. Update the OS: apt update && apt upgrade -y
  2. Update the Docker service: pull new images, docker compose up -d
  3. Update the application itself if vendor provides an upgrade script
  4. Test that the service still works

Phase 4: Clean Migration to New Server

  1. Provision the target server
  2. Install Docker and dependencies
  3. Copy docker-compose.yml and .env from source
  4. Export/import data using the application's native backup/restore:
    • PostgreSQL: pg_dump --format=custom on source → pg_restore on target
    • SQLite: Copy the .db file (service must be stopped)
  5. Update DNS records
  6. Test via the new DNS name
  7. Keep old server running for 7 days as rollback

Tags to Track in Todo

When the user adds multiple migration tasks, use consistent tags:

  • Backup <service> — <snapshot-method> → <target-server>

When NOT to Use This Pattern

  • Database-only services (< 1GB data): Direct pg_dump + S3 upload is faster
  • Hermes itself: Use the hermes-migration skill for state.db and Telegram
  • Small Docker stacks (N8N, Mautic): Direct docker compose up -d on new box with S3 data restore works fine