Inference & Ops
Deploying & one-click self-update
Lesson 10 of 10
What you'll learn
- See how a Go binary is deployed and kept running with systemd
- Understand the release flow for a cross-platform desktop app
- Model the desktop self-updater as a state machine
The relay is a single cross-compiled Go binary — no runtime, no dependencies — so deploying it is "copy a file and keep it running." You build for Linux, scp it to the VPS, and let systemd supervise it: start on boot, restart on crash, capture logs.
GOOS=linux GOARCH=amd64 go build -o quorum-relay .
scp quorum-relay root@vps:/opt/quorum-relay/quorum-relay-new
ssh root@vps "cd /opt/quorum-relay && mv quorum-relay quorum-relay-bak \
&& mv quorum-relay-new quorum-relay && systemctl restart quorum-relay"
# /etc/systemd/system/quorum-relay.service
[Service]
ExecStart=/opt/quorum-relay/quorum-relay
Restart=always # supervise: bring it back if it exits
[Install]
WantedBy=multi-user.target
Restart=always is the supervision contract: if the process dies, systemd starts it again. The dashboard is a Next.js app that ships to Vercel, and the desktop app is built per-platform and published to GitHub Releases.
Updating the thing on people's machines
A desktop app can't redeploy itself the way a website does — it's a binary already installed on someone's computer. So Quorum self-updates: it checks the latest release, and if there's a newer version, downloads the bundle, replaces itself on disk, and relaunches — no manual reinstall. The flow is a small state machine, and each step can fail and recover.
Replace, then relaunch — in that order
You can't overwrite a running binary in place on every OS. The updater downloads to a temp path, swaps the bundle, then relaunches into the new copy. Get the order wrong and you relaunch the old version or corrupt the install.
The challenge models the updater: compare versions, then walk download → replace → relaunch, short-circuiting when already current.
Run it. It updates when a newer version exists and no-ops when current. Try setting latest = current.
Why must the updater replace the bundle before relaunching, rather than after?
That's the full stack — from a single node holding a model to a self-updating fleet reachable from anywhere. You now have the mental model for every layer of Quorum.
Saved on this device. Sign in to sync your progress everywhere.