Skip to content

Stack Migration

Stack Migration moves a running stack from one host to another, including named volumes, with pre-flight checks, health verification, and automatic rollback on failure.

  • Decommissioning a host
  • Rebalancing load across a fleet
  • Moving from bare metal to a VM (or the other way)
  • Consolidating staging onto fewer hosts to save cost
  1. Open the stack’s detail page
  2. Click Migrate in the header (only visible when more than one host is available)
  3. Pick the destination host
  4. Review the pre-flight report and confirm

Pre-flight today is host-centric rather than per-container: dockmesh checks whether the target can reasonably take the load before any data moves.

CheckWhat it validates
target_onlineThe destination agent is reachable and accepting commands
no_concurrentNo other migration is already running for this stack
source_onlineThe source agent is still reachable for read-back
source_metricsCPU + memory snapshot from source so we can size the target headroom
target_capacityTarget has at least 1.2× the source’s used memory free
target_diskTarget has at least 1.1× the source’s used disk free

If any check fails, the migration won’t start. Image-pullability, port collisions, and Docker-version compatibility aren’t separately gated yet — they surface during the deploy phase on the target host if they apply, and the migration rolls back from there.

  1. Source stack is stopped (no live-replication mode today — workload is offline for the duration of the transfer)
  2. Named volumes are streamed over the mTLS tunnel from source to destination using a chunked tar protocol — both sides run a helper container scoped to the volume
  3. compose.yaml (+ .env) is shipped to the destination
  4. Stack is started on the destination and waits for the per-service healthcheck (or, where no healthcheck is defined, until all containers report running)
  5. On success: the source files + volumes stay on the original host for 72 hours as a safety window — they are not auto-pruned. After that window the background cleaner logs a reminder, and you delete them with DELETE /stacks/{name}/migrate/{id}/source (or via the migration’s detail page).
  6. On failure: the destination stack is removed, the source is restarted, and the failure is recorded so the migration can be inspected later.

The user-visible flow is atomic — if any step fails you end up back on the source host with the source running.

Bind-mounted paths (e.g. /opt/data:/app/data) are not moved because they point to host-specific filesystem paths. The pre-flight notes them; you either ensure the same path exists on the destination or convert the bind to a named volume before migrating.

While the 72-hour safety window is still open, a completed migration can be rolled back: stop the target stack, redeploy the source from the retained volumes + files, mark the migration as rolled-back. Triggered via the migration’s detail page (POST /api/v1/migrations/{id}/rollback). Once the source files are purged the rollback option is gone — pair high-risk migrations with a backup if you need a longer recovery window.