--- title: LXC Service Migration — Contabo → edge2 type: runbook tags: - proxmox aliases: [] related: - [[expose-service-edge2]] - [[caddy]] - [[expose-service-contabo]] - [[services]] - [[matrix_host]] updated: 2026-07-13 --- # LXC Service Migration — Contabo → edge2 > **Note on the source host references below:** Contabo (`100.64.0.1`) was the migration **source** host during the 2026-06 service evacuation and was decommissioned/rebuilt as **edge1** (mail-only) on [[2026-06-19]] — it no longer exists at that tailnet address. The `ssh root@100.64.0.1` commands throughout this runbook are illustrative of "the source host you are migrating from"; for any future migration, substitute the actual current source host and its real access pattern. edge2 targets always use `ssh edge2` + `sudo pct exec` — never `ssh root@` (root SSH is refused on edge2). See [[edge2-access-reference]]. The migration **pattern** itself (phases, gates, rollback structure) remains valid regardless of which host is the source. > Proven pilots: **Vaultwarden → edge2 CT 102** (SQLite, 2026-06-16), **Forgejo → edge2 CT 103** (PostgreSQL + non-Caddy SSH port, 2026-06-16), **LiveSync (CouchDB) → edge2 CT 104** (cold named-volume tar + bind-mounted config, 2026-06-16), **[[authentik]] (PostgreSQL keystone) → edge2 CT 105** (SECRET_KEY-must-travel, multi-block [[caddy]] cutover across 2 site blocks, reboot tailscale-before-docker race, 2026-06-18), **Matrix stack → edge2 CT 106** (multi-DB Postgres + stateful Signal bridge, 5 containers, 2026-06-18), and **Headscale → edge2 CT 107** (tailnet control plane, noise_private.key must travel, 2026-06-19). This runbook generalizes these patterns into a reusable template for evacuating any Contabo-Caddy-fronted service to an edge2 LXC. --- ## Overview Move a Docker service from the main Contabo VPS into an LXC on edge2, with the Contabo [[caddy]] frontend unchanged (public [[dns]] never moves; only the upstream token in the Caddyfile changes). Rollback is a single line. **Architecture after migration:** ``` Internet → 5.189.158.149 (Contabo Caddy) → 100.64.0.XX:PORT (edge2 LXC, via tailnet) ``` **edge2 access (always):** `ssh admin@184.174.35.153` (alias `edge2`, key `~/.ssh/contabo2_ed25519`), then `sudo` for every `pct`/`pvesm`/`pveam` command. `root@100.64.0.26` is refused — do not use it. --- ## Phases ### Phase 0 — Recon & baseline `[G]` - On Contabo (`ssh root@100.64.0.1`): capture the **verbatim** `.echo6.co` Caddy block (this is your rollback baseline). Grep the whole Caddyfile for any sub-routes related to the service. - Read the live compose file + `.env` + data directory listing **from the running host**. Never use `.ref/archive` docs — they may be stale. - On edge2 (`ssh edge2`): - Confirm the next free CT ID: `sudo pvesh get /cluster/nextid` - Confirm chosen IP is free: check `sudo pct list` and the `10.10.10.x` allocation table in `ip-allocation.md` - Check for needed template: `sudo pvesm list local | grep `. If absent: `sudo pveam download local ` - Confirm storage free space: `sudo pvesm status` - **Rollback:** n/a (read-only except optional template download). **Service-specific (example: Vaultwarden):** greppeed for `:3012`/`notifications/hub` sub-routes — none existed. Confirmed CT 102 and 10.10.10.20 free. --- ### Phase 0a — Pre-migration gate `[S]` Confirm any service-specific preconditions before provisioning (e.g., local login works, data is sane, credentials are recorded). **Service-specific (example: Vaultwarden):** Verified ≥1 account has a non-empty `password_hash` (local login works without SSO). Recorded `ADMIN_TOKEN` to credentials file. --- ### Phase 1 — Provision the LXC `[G]` Pick right-sized resources for the service (not a copy of another CT's sizing). ```bash ssh edge2 "sudo pct create local:vztmpl/