Upgrades
Update a self-hosted pod with synap update, choose a release channel, turn on automatic updates, and read the outcome.
Pods are updated from published releases. Each release has a signed manifest that pins every image by digest, so an update installs exactly what was tested.
Update now
cd /opt/synap/deploy
sudo synap update # the default channel: SYNAP_UPDATE_CHANNEL, else stable
sudo synap update --release stable # the latest tagged release
sudo synap update --release fast # the latest successful build of main
sudo synap update --release v1.1.3 # one specific release| Option | Meaning |
|---|---|
--release <ref> | A release ID (vX.Y.Z or main-<sha>) or a channel (stable, fast). |
--force | Re-apply the release the pod is already on. |
--from-source | Build the checkout as images and apply it like a release. For development on a clone. |
An update never falls back to building images on the server: without --from-source it only pulls the release's
images, and a failed pull stops the update before anything changes.
Options from older versions are still accepted, so scripts keep working: --build, -b, --local and -l mean
--from-source; --version <ref>, -v <ref> and a bare <ref> mean --release <ref>; latest means the default
channel; --from-image is ignored.
What an update does
Every update runs the same steps:
- Takes the update lock, so two updates never run at once.
- Fetches the release manifest and checks its signature (see Verifying releases).
- Checks free disk space (at least 2 GB by default) and pulls the images by digest. A failed pull stops here, before anything changed.
- Takes a verified
pre-updatedump of every database. - Runs database migrations.
- Starts the new backend as a canary and checks it.
- Swaps the backend, brings up every other service and verifies that they are healthy.
- Records the outcome.
If any step fails, the update rolls back to the previous images, and restores the pre-update dump when the
migrations had already changed the database.
The outcome
Every update writes its result to deploy/state/last-update.json. After a rollback (rolled_back,
rollback_failed or failed), every pod admin gets an in-app notification.
Automatic updates
Automatic updates on a self-hosted pod run from systemd. Install the units, with automatic updates on:
sudo synap units install --enable-auto-update
sudo synap units statusThis installs:
synap-heal.timer: every 2 minutes, restarts this pod's unhealthy containers, within a budget (never PostgreSQL).synap-update.path: applies update requests written todeploy/state/requests/update.json.synap-compose.path(releases after v1.1.3): applies service requests from the pod agent, written todeploy/state/requests/compose.json.synap-update.timer(only with--enable-auto-update): once a night, from 03:00, applies the latest release of the pod's channel within the update window.
The automatic run reads deploy/state/update-policy.json: auto (false turns it off), pinned (true holds the
pod on its release), channel and window (default 03:00-05:00). Automatic updates always require a valid
release signature (SYNAP_RELEASE_VERIFY=enforce).
Without systemd, synap units install prints a cron line for the heal task instead; updates are then manual.
Release channels
| Channel | What it follows |
|---|---|
stable | Tagged releases (v*). The default. |
fast | Every successful build of the main branch. |
Set the default channel for synap update with sudo synap config set SYNAP_UPDATE_CHANNEL=fast.
Before a release with upgrade notes
Some releases change something you operate, for example a new setting or a new outbound connection. These are listed
in the "Upgrade notes" of deploy/README.md in the
backend repository, newest first. Read them
before moving across several releases at once.
