Continuous deployment
Production is deployed by the deploy workflow of entrosity-infra
(.github/workflows/deploy.yml), since the cutover from the
entrosity/RMM monorepo on 2026-09-26 (entrosity-infra CUTOVER.md).
The monorepo's deploy, agent-builds, release and platform-cutover
workflows are disabled. Deploys never run in parallel and are never
interrupted.
A deploy runs when:
- a product repository publishes a new image from
mainand sends adeployrepository_dispatch:entrosity-axis.backendandentrosity-hub.backend(theimagejob of theirci.ymlpushesghcr.io/entrosity/{axis,hub}-backend:mainand:main-<sha12>once the checks pass onmain), andentrosity-axis.frontend,entrosity-hub.frontendandentrosity-docs(after pushing their static:mainimages).entrosity-edge.*,entrosity-sphere.*andentrosity-matrix.*publish their:mainimages the same way but do not send the dispatch yet: their images go out with the next deploy; - a push to
mainofentrosity-infrachangesdeploy/; - it is run by hand (Actions → deploy → Run workflow). With stage-only
it loads the images and syncs
deploy/on the host without restarting anything.
Every run deploys the current main image of every component, so the
order in which the product repositories finish does not matter.
No registry is needed on the host: images are streamed over SSH. The
production images are axis-backend, hub-backend, edge-backend,
sphere-backend, matrix-backend and entrosity-web (before the cutover rmm-backend,
platform-backend and rmm-web); they ship together on the same
version, and upgrade.sh migrates and restarts Axis and the Hub, and
Edge, Sphere and Matrix on hosts that enable them (EDGE_ENABLED,
SPHERE_ENABLED, MATRIX_ENABLED; Running Entrosity Sphere,
Running Entrosity Matrix).
The run's summary lists the digest of every main image it deployed.
Each run pulls every backend's :main image and builds the web image
from every frontend's :main image, whether a host enables the product or
not. A missing image fails the whole deploy: push an entrosity-infra
change that adds a product (as for Entrosity Sphere and Matrix) only after its
backend and frontend images have been published
(Rollout).
The final check reads PLATFORM_DOMAIN from the host's .env and waits
(up to five minutes) for the agent API path of devices enrolled against
the old host ($DEPLOY_URL/api/v1/healthz), Axis's API on the Hub's host,
the Hub's API, and, where the host's .env enables them, Edge's
(/edge/api/v1/healthz), Sphere's (/sphere/api/v1/healthz) and
Matrix's (/matrix/api/v1/healthz). If they
do not answer, the workflow prints the services' status and the last log
lines of backend, platform and web, and fails.
Repository settings
In entrosity-infra:
| Secret | Value |
|---|---|
ENTROSITY_CI_TOKEN | Reads the private images from GHCR (read:packages). |
DEPLOY_HOST | The host's address. |
DEPLOY_SSH_KEY | A private key whose public half is in root's authorized_keys on the host. |
DEPLOY_KNOWN_HOSTS | The output of ssh-keyscan <host>, which pins the host key. |
| Variable | Value |
|---|---|
DEPLOY_ENABLED | Must be true; anything else skips every run except a manual stage-only one (kill switch). |
DEPLOY_URL (optional) | Axis's old host, checked at the end together with the Hub's host (default https://manage.entrosity.com). |
The host
- Docker with the compose plugin, and a filled-in
/opt/entrosity/deploy/.env(Installation). The workflow never touches.envorbackups/. The compose project is still calledrmm, and the systemd unitrmm.servicestarts the stack from/opt/entrosity. - PostgreSQL 18 keeps its data in the volume
rmm_postgres18-data(mounted at/var/lib/postgresql). Production moved from PostgreSQL 16 withpg_dumpalland apsqlrestore during the cutover; the old volumermm_postgres-dataand the monorepo's stack in/opt/rmm/deployare kept for rollback until they are removed. - On a 2 GB host, set
PG_SHARED_BUFFERS,PG_EFFECTIVE_CACHE_SIZEand the backend memory in.env, and add 2 GB of swap.
Rolling back
Run deploy/scripts/deploy.sh <older version> on the host (the images of
the previous two versions are still there), or re-run an older workflow
run.
Agent and connector builds
The agent and connector MSIs are built by entrosity-axis-agent and
entrosity-axis-connector (dev-release.yml on every push to main,
release.yml on tags), which attach them to GitHub releases and publish
them to production as self-update releases (RELEASE_PUBLISH_ENABLED=true
with the secrets RELEASE_PUBLIC_KEY and RMM_RELEASE_TOKEN in both
repositories; the builds are unsigned). Dev builds are versioned
0.1.<run>-dev.<sha>. See
Agent releases and
CI workflows.