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

```bash
# 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
