Skip to content

Upgrading

Rod Christiansen edited this page Oct 8, 2026 · 2 revisions

Upgrading

Upgrading this stack means moving both application images to a new tag. The schema follows automatically; the API self-applies migrations on startup.

Image tags

One variable, REPORTMATE_TAG, sets the tag on both ghcr.io/reportmate/web and ghcr.io/reportmate/reportmate-api. It defaults to latest. The two images are published by different repos with different tag schemes, so the only tag both images carry is latest:

Image Published by Tags
ghcr.io/reportmate/reportmate-api reportmate-api CI on every push to main and on v* tags latest and main (default branch), sha-<full commit>, and on a v1.2.3 tag both 1.2.3 and 1.2
ghcr.io/reportmate/web reportmate-app-web on a v* or YYYY.MM.DD.HHMM git tag, or a manual run the git tag as written (for example 2026.09.16.1139) and latest

latest moves at different times on each image: the API's moves with every merge to main, the dashboard's only when a release tag is pushed. A plain docker compose pull can therefore move you to versions you did not choose.

To pin, replace ${REPORTMATE_TAG:-latest} on each image: line in docker-compose.yml with a tag that exists for that image, for example ghcr.io/reportmate/reportmate-api:sha-<full commit> and ghcr.io/reportmate/web:2026.09.16.1139. Pick a dashboard release and an API build from the same period; the two share the API_INTERNAL_SECRET contract and the API's /api/v1/ routes.

The tags that exist are listed on each repo's Packages page.

The upgrade

  1. Take a database dump. See Backup and Restore — the API migrates the schema forward on startup and there is no downgrade path.
  2. Change the image tags (REPORTMATE_TAG in .env, or the pinned tags in docker-compose.yml) to the new versions.
  3. Pull the new images:
docker compose pull
  1. Recreate the containers:
docker compose up -d

Compose recreates api and web because their image changed, and leaves postgres alone. Expect a short outage while both restart.

  1. Confirm the API is healthy before you consider it done:
curl http://localhost:8000/api/v1/health

What happens to the schema

schema/init.sql runs only on an empty data directory, so it plays no part in an upgrade. The API image carries its own migrations and applies them when it starts, and it re-ensures indexes and the settings table idempotently. An existing database therefore self-updates the first time the new API container comes up.

This also means the API container may take longer than usual to answer on the first start after an upgrade. Watch it rather than assuming a hang:

docker compose logs -f api

Rolling back

Set the image tags back to the previous versions and repeat pull and up -d. This works only if the newer version applied no migration the older code cannot read. If the release notes mention a schema change, roll back by restoring the dump you took in step 1 instead.

Upgrading Postgres itself

The postgres service is pinned to postgres:16-alpine in the Compose file, not driven by a variable. Moving to a new Postgres major version is not an in-place edit of that line — the existing postgres_data volume belongs to the old major. Dump, remove the volume, change the image, and restore.

Upgrading an appliance

An appliance built by Packer runs the same project from /opt/reportmate, but under reportmate.service, which holds docker compose up in the foreground. Edit /opt/reportmate/.env, pull the images, then restart the unit rather than running up -d beside it:

sudo systemctl restart reportmate.service

Alternatively, build a fresh image from a checkout whose image tags point at the new versions and restore your dump into it. See Appliance Image.

Clone this wiki locally