Upgrades
Upgrade a self-hosted installation without losing data or plugin compatibility.
Back up first; see Database Migrations. For runtime settings, see Configuration. For the deployment this upgrades, see Self-Hosting.
How releases and images are tagged
erxes versions are cut with release-it (pnpm release): .release-it.json tags the release commit as <version> (tagMatch: 3.*) and updates CHANGELOG.md from conventional commits. Tag pushes then trigger release.yml, which re-tags a fixed matrix of Docker images (erxes/erxes-next-core-api, erxes/erxes-next-gateway, erxes/erxes-next-ui, erxes/erxes-next-logs, erxes/erxes-next-automations, all eleven erxes/erxes-next-<plugin>_api images, plus erxes/frontline-widgets, erxes/posclient-front, and erxes/help-center) from :latest to :<version> using docker buildx imagetools create. erxes/erxes-next-migrations is published by its own CI workflow but is not in the release matrix, so it has no :3.1.x tag; pin it by latest or digest.
So a released version does produce matching :3.1.9-style tags across all core and plugin images, but each tag aliases whatever :latest was at release time. Between releases, CI also publishes floating latest plus per-service tags (YYYYMMDD-<short-sha> for APIs and services, full commit SHA for the gateway, branch/SHA/semver metadata tags for UI and apps). Prefer an explicit version tag or digest over latest so rollback is a config change, not a guess.
Plugin frontends are not images: the ci-ui-* workflows sync each *_ui build to the plugins.erxes.io CDN under latest/ or the release tag. Enabling a plugin version whose UI assets were not published breaks its navigation; see Frontend & Plugin Loading.
Reading the changelog: 3.1.6 to 3.1.9
CHANGELOG.md is the source of truth for what each release changed. For the 3.1.6 to 3.1.9 jump:
3.1.7added OAuth scope-per-plugin-module fixes, a compactuserheader with a 64 KB header budget, document locking, milestone/GitHub-issue sync, and a call-widget cache control.3.1.8fixed call transfer, content Postiz delivery (tenant routing, JWT signing, QEMU-safe builds), MS Dynamics customer checks, and frontline surveys; it added conversation→ticket/deal/task conversion andCALLPRO_SUBDOMAINSgating.3.1.9added "Basic information" system fields in Settings → Properties, member email activity logs, and frontline convert-property visibility.
None of these releases document a required manual migration. The changelog only tells you what each release includes; confirm by diffing backend/saas-migrations/ and plugin src/migrations/ directories between your tags, as described in Database Migrations.
Upgrade procedure
Choose a compatible image set
List every image you run (Core UI, gateway, Core API, logs-service, each
*_api, any apps), pick one version tag or digest for the whole set, and record current references for rollback:docker compose images docker images --digests | grep erxesBack up and stage
Take a restorable
mongodumpof the application database and<db>_logs(Database Migrations). Restore it to staging, deploy the candidate image set with the production.envshape, run any new migration scripts, and verify login, enabled plugins, automations, file URLs, and customer-facing apps.Upgrade production
Announce the window; a single-server Compose update causes a short outage. Update the image references in
.env, then:docker compose pull docker compose up -d docker compose psWait for Core API to register and the gateway to recompose its supergraph (the
gateway-update-apollo-routerjob handles plugins that join after startup). Run migration scripts for the release if it includes them.Check it works
Check
/healthon gateway and Core API, the__typenameGraphQL probe, owner login, and one representative flow per enabled plugin, including the plugin's remote UI (/get-frontend-pluginsmust return reachableremoteEntry.jsURLs). Keep the previous image digests and the pre-upgrade backup until the new version is stable.
Rollback
- Restore the previous image references in
.envand rundocker compose up -d. - Restore the pre-upgrade database backup only if a migration changed stored data and a forward fix is riskier; restoring loses writes made after the backup.
- Re-verify health, GraphQL, login, and plugin UI loading.
Rollback does not undo migrations
Recreating containers with older images reverts code, not data. If the release ran a data migration, the only safe rollback is the backup taken before it ran.