Upgrades
To upgrade self-hosted Stategraph, run a newer tag of the Stategraph container. It migrates its databases at start, with no separate migration step.
Pick a version
The releases page lists versions and notes. In production, pin a version tag, not latest:
services:
server:
image: ghcr.io/stategraph/stategraph-server:2.5.7
Then:
- Docker Compose:
docker compose pullanddocker compose up -d - Kubernetes: set
stategraph.image.tagand runhelm upgrade - Amazon ECS: set
stategraph_imageand runterraform apply - Google Cloud Run: mirror the new tag into Artifact Registry, update
image:in the service definition, and redeploy
Releases follow semantic versioning. For the CLI and images, see Releases.
Boot-time migrations
At each start, Stategraph migrates the stategraph database, then serves requests. With Orchestration on, it also migrates the terrateam database, in parallel and with no order dependency.
- Stategraph checks that the applied migrations are a prefix of its own list. If they differ, it exits non-zero and applies nothing on top.
- Each migration commits by itself, so an interrupted run leaves a consistent prefix, never a partial migration.
- Replicas that migrate at the same time are safe: primary keys guard the bookkeeping rows. The loser of the race fails with a visible duplicate-key error, retries at restart, and never applies a migration twice.
/health/readyanswers502until Stategraph has migrated and serves, so a load balancer or readiness probe keeps traffic on the old containers./health/liveanswers200as soon as Stategraph listens on port 8080. See Health checks.- After a failed Orchestration migration, Stategraph waits 30 seconds before it retries, so retries come at a steady interval with the error in the log.
- A failed Stategraph server restarts every few seconds. In Docker Compose, the container waits for a healthy PostgreSQL through
depends_on. - With Orchestration on, the
stategraphmigration also drops and rebuilds thepostgres_fdwbridge toterrateamat each start. On managed PostgreSQL, this needs superuser rights: see Enable Orchestration.
Rolling replacement
At stop, Stategraph refuses new requests, finishes those in progress, then shuts down, within a 60 second grace period. Give the container that period: stop_grace_period: 60s in Compose, stopTimeout of 60 on ECS, or terminationGracePeriodSeconds: 60 on the pod. Stopping it sooner cuts requests short.
For zero downtime, run several replicas and let readiness control traffic. Set the same STATEGRAPH_OAUTH_COOKIE_SECRET on each, so that sessions survive.
Behavior changes to check
Read the release notes of the versions that you skip. These changes affect running self-hosted deployments:
- 2.5.7: The container sets
TERRAT_SESSION_COOKIE_NAME=terrat_session, so the Orchestration session cookie no longer collides with the consolesessioncookie. A deployment that replaces the whole container environment must keep it, or a VCS OAuth callback signs console users out. - 2.5.6: Orchestration does not start when
GITHUB_APP_IDis set withoutGITHUB_WEBHOOK_SECRET, and no longer accepts unsigned webhook events. A running deployment with GitHub credentials and no secret stops starting Orchestration until you set one. Only the container log shows the failure. - 2.5.2: The self-hosted setup wizard image moved to
ghcr.io/stategraph/orchestration-setup. - 2.5.2: The users API renamed
/api/v1/users/toggle-adminto/api/v1/users/set-instance-adminand theis_adminfields tois_instance_admin, and addedis_tenant_admin. Update API clients that create or delete users.
Verify an image
Released images have a Sigstore keyless signature and a SLSA build provenance attestation. The signing certificate records the repository, release workflow, and source commit. Check it with cosign before you run a new tag:
cosign verify \
--certificate-identity-regexp '^https://github\.com/stategraph/mono/\.github/workflows/release\.yml@' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
ghcr.io/stategraph/stategraph-server:2.5.7
Read the provenance with the same identity:
cosign verify-attestation --type slsaprovenance1 \
--certificate-identity-regexp '^https://github\.com/stategraph/mono/\.github/workflows/release\.yml@' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
ghcr.io/stategraph/stategraph-server:2.5.7 \
| jq -r .payload | base64 -d | jq .predicate
The predicate names the builder, the source commit, and the workflow run that built the image.
latestresolves to the same digest as its version, so both tags check the same signature.- The per-arch tags
<version>-amd64and<version>-arm64have their own signature and provenance, and both commands accept them with the same identity flags. - The CLI image,
ghcr.io/stategraph/stategraph, verifies the same way. - Tags before 2.5.2 have no signature, and
cosign verifyfails for them.
Next steps
- Releases: downloads, the CLI, and release notes
- Health checks
- Environment variables