Skip to content

Updating

Doug edited this page Aug 8, 2026 · 6 revisions

Updating

How to move a running instance to a newer version safely. Migrations run automatically on boot; the thing that protects you is the pre-update database snapshot — keep it.

Knowing an update exists

Admins see a version badge on the System Admin page: it shows the running APP_VERSION and a "update available → x.y.z" tag when a newer GitHub release exists (GET /api/admin/update-check compares against the latest release).

Path A — published image (recommended for self-host)

Published releases live on GHCR — ghcr.io/freeperro/gdx_dispatch (:latest points at the newest release; see the repo's Releases page for the current version). Cut a new one by pushing a vX.Y.Z tag (see the bottom of this page).

If you run the published image via the self-host overlay (see the README's Self-hosting section), upgrading is one script:

# pin the target release in .env (or leave APP_VERSION unset to track :latest)
echo 'APP_VERSION=1.45.0' >> .env

./gdx_dispatch/docker/update.sh
# or pin inline:  APP_VERSION=1.45.0 ./gdx_dispatch/docker/update.sh

update.sh does, in order:

  1. Snapshot the database → backups/gdx-pre-update-<ts>.sql.gz.
  2. Pull the new images.
  3. Start app alone first — only the app runs migrations (workers skip them), so exactly one container migrates, no race.
  4. Wait for /health (up to HEALTH_TIMEOUT, default 600s — a real DDL migration can take minutes; HEALTH_PORT overrides the probed port, default 8001).
  5. Once healthy, start the workers.

Set EXTRA_COMPOSE=<file> to layer an additional compose override into every step (e.g. a local nginx or port tweak).

If health doesn't come up, the script tells you whether the app is still migrating (don't roll back yet — watch the logs) or has crashed (safe to roll back, with the exact restore commands printed).

Rolling back

# 1. pin the previous release in .env:  APP_VERSION=<old>
# 2. restore the pre-update snapshot:
gunzip -c backups/gdx-pre-update-<ts>.sql.gz | \
  docker compose -p gdx --env-file ./.env \
    -f gdx_dispatch/docker/docker-compose.yml \
    -f gdx_dispatch/docker/docker-compose.selfhost.yml exec -T db psql -U gdx gdx
# 3. bring it back up:
docker compose -p gdx ... up -d

Path B — build from source

If you run the plain dev compose (up --build, no published image):

docker compose -f gdx_dispatch/docker/docker-compose.yml exec -T db \
  pg_dump -U gdx gdx | gzip > "pre-update_$(date +%F).sql.gz"   # snapshot first!

git pull
docker compose -f gdx_dispatch/docker/docker-compose.yml up -d --build

The app container re-runs migrations on boot.

Notes

  • Always snapshot first. Path A does it for you; Path B you do manually (above).
  • Updating plugins is separate from updating the core app — see Using Plugins.
  • Publishing releases (so Path A has images to pull) is a maintainer step: push a vX.Y.Z tag → CI builds, smoke-tests, and pushes the image to GHCR.

See also

Clone this wiki locally