2.4 KiB
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:
- Update the OS:
apt update && apt upgrade -y - Update the Docker service: pull new images,
docker compose up -d - Update the application itself if vendor provides an upgrade script
- Test that the service still works
Phase 4: Clean Migration to New Server
- Provision the target server
- Install Docker and dependencies
- Copy docker-compose.yml and .env from source
- Export/import data using the application's native backup/restore:
- PostgreSQL:
pg_dump --format=customon source →pg_restoreon target - SQLite: Copy the .db file (service must be stopped)
- PostgreSQL:
- Update DNS records
- Test via the new DNS name
- 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-migrationskill for state.db and Telegram - Small Docker stacks (N8N, Mautic): Direct
docker compose up -don new box with S3 data restore works fine