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

Pie chart of 39 recovery units: teal 25 moved or redeployed, 64.1 percent; orange 14 still on the source or awaiting retirement, 35.9 percent.
Migration placement at this checkpoint: teal is 25 of 39 units moved or redeployed; orange is 14 left to migrate or retire. Placement does not imply every acceptance test is complete. Original chart by Aura.

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.

Similar Posts