# Upgrade

Upgrading an instance means backing it up, running the image of the new version, and letting it migrate its database at start; migrations only go forward, and an older image refuses a newer database.

## Steps

1. **Read the release notes.** A patch or a minor release needs nothing else; a major one says what to change first ([versioning policy](https://github.com/vaubaan/gateway/blob/main/docs/workflow/coding-workflow.md#versioning-policy)).
2. **Back up** the database and keep the master key with the copy ([backup](/docs/operations/backup-and-restore)).
3. **Take the new version.** Until a release exists, that is the new commit of the repository: `git pull`, then rebuild and restart with the same Compose command as the install:

   ```bash
   docker compose --env-file deploy/config/.env -f deploy/compose.yaml up -d --build
   ```

   On Railway, deploy a verified build of the new commit ([Railway, step 5](/docs/install/railway#5-deploy-a-verified-build)).

4. **Check** `/healthz`: it answers the new version and commit.

Schema migrations run at start, forward-only and checksummed. There is no downgrade: keep the backup of step 2 until you are sure.

## Once releases exist

Releases will be published at `ghcr.io/vaubaan/gateway` (none exists yet). Then: replace the `build:` block of the `gateway` service in `deploy/compose.yaml` by `image: ghcr.io/vaubaan/gateway:<version>`, verify the image's provenance before the first start, and pin the digest you verified. The commands: [deploy README, Released images](https://github.com/vaubaan/gateway/blob/main/deploy/README.md#released-images).

## Changing the identity provider

A person is the pair (issuer, subject), so another identity provider means new accounts for everybody; the earlier ones keep their accounts and missions and are reached by nobody. When you upgrade an instance that already has users, let somebody sign in once **before** you change `idp.*`.
