Updates & versioning
One-command server updates, and how desktop versions follow.
Updating a self-hosted Proliferate is one command on the server, and your users' desktop apps follow automatically; you never coordinate a separate desktop rollout.
Update the server
Run ./update.sh from your deploy directory (the extracted
proliferate-deploy bundle you deployed from). Under the hood it runs the
sequence:
Pull
Pull the server image at the tag configured in .env.static
(PROLIFERATE_SERVER_IMAGE_TAG).
Migrate
Run database migrations in a one-shot container before the new server starts.
Restart
Restart the stack (docker compose up -d).
The script also re-checks that generated secrets exist, refreshes the runtime
binaries on the host under /opt/proliferate/bin when the cloud sandboxes
add-on's runtime-binary variables
are set, and health-checks the stack before it exits, so a completed run
means the new version is actually serving.
Screenshot: Terminal, update.sh finishing with a passing health check
A terminal running ./update.sh through pull, migrate, and restart, ending with the stack reported healthy.
Model gateway operators: update.sh does not touch litellm. The bundled
gateway services run under the opt-in agent-gateway Compose profile, and
plain pull/up skip profiled services entirely. After update.sh, also
run docker compose --profile agent-gateway pull and
docker compose --profile agent-gateway up -d to refresh the gateway. See
Model gateway. Installs without the
gateway can ignore this.
To confirm the version after an update:
Version pinning: a release tag vs stable
The server image is ghcr.io/proliferate-ai/proliferate-server, published
with per-release version tags and a stable tag. You choose which one you
track with PROLIFERATE_SERVER_IMAGE_TAG in .env.static:
- Pin a release tag (for example
0.3.0) for change-controlled environments.update.shthen only moves you when you edit the tag, so an update is an explicit, reviewable change. - Track
stableto pick up releases whenever you runupdate.sh, with no file edits.
Releases are published on GitHub as server-vX.Y.Z, and the deploy bundle
(proliferate-deploy.tar.gz) is attached to each release. The support
intent is N releases back: staying a few releases behind is fine, and
update.sh is the one operator motion that catches everything up.
How desktops stay in lockstep
The server you run is the version root for the whole fleet:
GET /metaon your server reportsserverVersion,desktopVersion,runtimeVersion, andminDesktopVersion. Each server release is stamped with the desktop and runtime versions it shipped with.- Connected desktop apps check
GET /desktop/updater/latest.jsonon your server, which responds with a 302 redirect to the official CDN update manifest for the version your server pins. When the manifest for that exact version is not published (a server built ahead of a desktop release, or a release that predates versioned manifests), the server redirects to the latest stable manifest instead, so update checks always land on a valid manifest. Your server carries only a version number; it never builds or serves desktop binaries. - The desktop app verifies every update against the signing key baked into the official build, no matter which endpoint served the manifest. A server can choose which version desktops run, but it can never ship a modified build.
minDesktopVersionis the compatibility floor: desktops older than it are told to update before they can keep working against your server.
The net effect: when you run update.sh, your users' apps converge on the
matching desktop version on their own.
Cloud sandbox operators: rebuild your E2B template after every server
update. The sandbox template bakes in runtime binaries that must match the
server version, and E2B templates live only in your own team, so nothing
rebuilds them for you. After update.sh, rerun the template build from a
repo checkout at the matching release (a containerized template builder that
removes the checkout step is planned). See
E2B & sandbox template.
Deployments without the cloud sandboxes add-on can skip this.
Data retention & backups
All persistent state lives in named Docker volumes on the host: the Postgres data volume (everything about your orgs, users, and sessions), Caddy's certificate volumes, and the small first-run setup-state volume. That means:
- Back up Postgres, with
pg_dumpor a volume snapshot, on whatever schedule your org requires. Taking a backup before runningupdate.shis cheap insurance, since migrations move the schema forward. - Data is kept until you delete it. The server does not yet ship automated retention windows for session data; scheduled purging is on the roadmap. If you have a hard retention requirement today, get in touch.
- Telemetry is separate from retention and is covered in Telemetry & privacy.