The Pi Swarm Migration: A Progress Check, Not a Victory Lap
There is a tempting moment in any infrastructure move when a dashboard fills with green 1/1 badges and you want to call it done. Our migration from an older Docker host to a four-node Raspberry Pi Swarm has reached that moment more than once. Each time, a public route, a stateful database, or a monitor has reminded us that a running task is only one piece of the story.
Here is the progress check, not the victory lap. The original recovery register contains 39 units; it has not yet been reconciled to 39 verified final dispositions. The move remains open.
Migration ledger: moved versus still to disposition

Teal: 25 of 39 recovery units moved or redeployed (64.1%). Orange: 14 of 39 still on the source or awaiting deliberate retirement (35.9%). The moved slice is a placement count, not a claim that all 25 passed every end-to-end acceptance test. In particular, PriceBuddy’s workers still need a real job test; routing and backup qualifications also remain open. The 14 include applications, host infrastructure, and archive-and-retire units.
What moved, and what we actually checked
RECENT CUTOVERS SWARM STATE END-USER ROUTE HomeLabel: three services 1/1 each SSO redirect responds* n8n + PostgreSQL 1/1 each Public health check: 200 Paperclip + PostgreSQL 1/1 each Public page: 200 PriceBuddy workers 1/1 each Worker health responds** * The login redirect tests the public SSO path, not a signed-in session. ** A successful real worker job has not yet been verified.
HomeLabel’s SQLite state moved only after its old writers were stopped. Its copied database passed an integrity check, and the target’s service trio came up. The public route now reaches the single-sign-on boundary. That is useful evidence, but it does not pretend we completed a human login and exercised every screen.
For n8n, we restored PostgreSQL into an isolated target, checked that stored credentials could be decrypted, and moved the public route after the new service responded. A vector-database sidecar presented an unusual wrinkle: its ARM64 build aborted on the Pi’s larger kernel page size. The source had no collections or points, and the workflows and credentials we inspected had no references to it. Rather than leave a crash-loop disguised as a migration, we deliberately set that service to zero replicas and recorded the retirement in the deployment definition.
Paperclip illustrated the difference between a healthy application and a healthy journey to it. The app and database were both running, yet the public route returned a gateway error. Narrowing the proxy to the actual service owner restored repeated successful responses. That is a working route, not a permanent repair of the underlying routing-mesh anomaly.
The monitoring had to move too
UPTIME KUMA RECONCILIATION Existing service checks repointed 6 |###### New public endpoint checks 3 |### Unchanged PriceBuddy endpoint 1 |# New checks: n8n, Paperclip, HomeLabel. HomeLabel accepts the expected login redirect; it is not an authenticated application-content test.
The six changed checks had still been aimed at the old service addresses. We pointed five port checks and one HTTP check at the running Swarm owners, then read each saved monitor back. Three new checks cover the public n8n, Paperclip, and HomeLabel routes. The existing PriceBuddy monitor already reached its endpoint and was left alone. These are configuration readbacks and endpoint probes; they are not a claim that an alert notification was delivered end to end.
The unfinished column matters
Several application stacks remain on the source, along with backup and management infrastructure that should be handled last. PriceBuddy’s two workers are alive with copied state, but a real job still needs to prove they do useful work. We also need to qualify backups for the new owners and fix the routing mesh instead of treating an owner-specific proxy as the final architecture. One monitor can say a port is open while all of those questions remain unanswered.
The lesson from this stretch is simple: for each stateful move, fence the original writer, verify the transferred data, exercise the application, exercise the real public path, and then make monitoring follow the new truth. A green 1/1 is a starting signal. It is not the finish line.

