Skip to content

Upgrading

The containers are disposable and the PostgreSQL volume is the only state, so an upgrade is "pull the new image, replace the container". What needs care is the schema policy described at the end of this page.

Before you upgrade

  • You have a database backup taken after the last change you care about (Backup & restore).
  • You have the master key stored outside the deployment.
  • You have read the release notes of every version between yours and the target, especially for a new major.
  • You know the current version: GET /v1/install/status reports the schema version (Health checks).

With Docker

docker pull quay.io/axiumlab/core:v0.2.0
docker stop axium-core && docker rm axium-core
# relaunch the docker run from the install guide with the new tag

Same for the ui. With Compose, change the tag in .env and run docker compose pull && docker compose up -d.

Upgrade the core first, then the ui: the console consumes the API, not the other way round.

On Google Cloud

infra-gcp/update.sh upgrades the core, the ui or both on an installation created by gcp.sh:

wget https://raw.githubusercontent.com/axium-lab/infrastructure-documentation/refs/heads/main/infra-gcp/update.sh \
  && chmod +x update.sh

bash update.sh                  # asks what to upgrade
bash update.sh core             # only the core
bash update.sh ui               # only the ui
TAG=v0.2.0 bash update.sh both  # both, on a specific version (recommended)

What it does:

  1. Checks that the services and the Artifact Registry repository exist. If not, it stops and points you at gcp.sh.
  2. When the core is included, re-applies the APIs and IAM roles the core needs (Cloud SQL, Cloud Storage, Vertex AI). Installations created by an older installer lack some of them, and without them the new core starts but answers 403 as soon as it touches a bucket or a Google model. Every binding is idempotent and none aborts the upgrade: without IAM permission the script warns and prints the command for whoever has it. SKIP_IAM=1 skips the step.
  3. Resolves the digest of the tag on Quay, copies the image by digest to Artifact Registry and deploys that exact digest. With latest this removes the window in which the tag could move between copy and deploy.
  4. Redeploys passing only --image. Cloud Run keeps everything else: environment variables, the Cloud SQL attachment, memory, concurrency and IAM. The script never reads or rewrites MASTER_ENCRYPTION_KEY or API_URL.
  5. Verifies /v1/install/status on the core and a 200 on the ui root.

Options: REGION= if you did not deploy to europe-west1, VERTEX_PROJECT= if Vertex AI lives in another project, DEBUG=1 for registry diagnostics.

Rolling back on Cloud Run

Every deploy creates a revision. To send traffic back to the previous one:

gcloud run revisions list --service axium-core --region europe-west1
gcloud run services update-traffic axium-core --region europe-west1 \
  --to-revisions <previous-revision>=100

Schema policy

Each image ships a schema version. At startup the core compares it with the database:

Database Action
Same version Nothing.
Older The bundled migrations are applied automatically, one version at a time, each in its own transaction and under an advisory lock, so several replicas can start together. Log: [install] schema migrated 1 -> 3.
Newer The process exits: The database is at schema version N but this build ships M. Update the API to the latest version. Schema never downgrades, so rolling back an image after a migration is not supported without restoring the database.

A failed migration exits the process instead of serving an unknown schema. That is why the backup comes first in the checklist above.

Major versions

Minor and patch releases keep migrations small and backward compatible. A new major may carry migrations that are expensive on a large database or that change behaviour. Read the release notes and, if in doubt, ask Axium Lab before moving up a major version.

If after an upgrade /v1/install/status reports anything other than installed, or the core exits on start, restore the backup, roll back the image and contact support with the output of:

docker logs axium-core | grep '\[install\]'