Skip to main content

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 main and sends a deploy repository_dispatch: entrosity-axis.backend and entrosity-hub.backend (the image job of their ci.yml pushes ghcr.io/entrosity/{axis,hub}-backend:main and :main-<sha12> once the checks pass on main), and entrosity-axis.frontend, entrosity-hub.frontend and entrosity-docs (after pushing their static :main images). entrosity-edge.*, entrosity-sphere.* and entrosity-matrix.* publish their :main images the same way but do not send the dispatch yet: their images go out with the next deploy;
  • a push to main of entrosity-infra changes deploy/;
  • 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.

Every run needs every image

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:

SecretValue
ENTROSITY_CI_TOKENReads the private images from GHCR (read:packages).
DEPLOY_HOSTThe host's address.
DEPLOY_SSH_KEYA private key whose public half is in root's authorized_keys on the host.
DEPLOY_KNOWN_HOSTSThe output of ssh-keyscan <host>, which pins the host key.
VariableValue
DEPLOY_ENABLEDMust 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 .env or backups/. The compose project is still called rmm, and the systemd unit rmm.service starts 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 with pg_dumpall and a psql restore during the cutover; the old volume rmm_postgres-data and the monorepo's stack in /opt/rmm/deploy are kept for rollback until they are removed.
  • On a 2 GB host, set PG_SHARED_BUFFERS, PG_EFFECTIVE_CACHE_SIZE and 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.