Upgrades
The image is ghcr.io/epure-sh/epure. There is no worker fleet or Redis stream to drain. Path: backup → git pull the clone → bump EPURE_IMAGE → compose up → watch health. Keep .env; Compose still interpolates it.
Pinning only the GHCR tag is not enough when the release also changes compose, .env.example, or deploy overlays — those files live in the git checkout. Operators who only changed EPURE_IMAGE and still saw old UI (for example Register after EPURE_REGISTRATION=false) needed a git pull first.
Upgrade in five steps
Dump Postgres, note the commit you are leaving, check out the new revision, bump the image pin, compose up (pulls GHCR), confirm /health.
Pin production
In production set EPURE_IMAGE=ghcr.io/epure-sh/epure:v0.1.7 in .env. Keep EPURE_REGISTRATION in that file when you bump the image. Current release: v0.1.7 (2026-10-04) — release notes, docs changelog.
Dump Postgres
docker compose exec -T postgres pg_dump -U epure -d epure -Fc > "epure-$(date +%Y%m%d).dump"Store the dump off-box. Prod overlay: same exec; Postgres has no host port.
Optional artifacts (if you upload maps):
Archive source-map volume
command
docker volume ls docker run --rm \ -v epure_artifacts_data:/data \ -v "$(pwd)/backups:/backup" \ alpine tar czf /backup/artifacts-$(date +%Y%m%d).tar.gz -C /data .
Note the git commit you are leaving.
Check out the new revision and pin the image
Check out the release tag
command
git fetch git checkout v0.1.7 # or: git pull origin main
In .env (create from .env.example if needed):
Pin the release image
command
EPURE_IMAGE=ghcr.io/epure-sh/epure:v0.1.7
Compose reads both the checkout (compose files, overlays) and EPURE_IMAGE. Skipping git pull leaves you on old templates even when the container tag is new.
Pull and start
Pull local stack
command
docker compose up -d
Migrations apply when the epure process starts. There is no separate migrate container.
Confirm health
docker compose logs -f EpureCheck health
Local default. Use EPURE_PUBLIC_URL/health if you changed the port or are on HTTPS.
command
curl -sS http://localhost:8080/health
Expected
{"status":"ok"}On production, use EPURE_PUBLIC_URL/health. Local default is http://localhost:8080/health. Then: login, Issues list, one store POST → 202. Quickstart Try ingest.
Roll back if it fails
Schema may move forward only. Restore the dump before starting an older binary if a migration is not backward-compatible.
Restore dump and previous binary
Keep Postgres up. Stop only the app, restore, then compose up the previous image.
command
docker compose stop Epure git checkout <previous-commit> docker compose exec -T postgres pg_restore -U epure -d epure --clean --if-exists < epure-YYYYMMDD.dump docker compose up -d curl -sS http://localhost:8080/health
Expected
{"status":"ok"}--clean drops objects before restore. Confirm /health and login. Keep EPURE_SESSION_SECURE matched to HTTP vs HTTPS.
What stays the same
No upgrade introduces Redis or a worker fleet.
- Two-container topology (app + Postgres 16)
EPURE_MODE=all- RLS session variable:
app.current_org_id - Volume names for Postgres and artifacts (unless you rename the Compose project)
Checklist
- Dump taken and stored off-box
- Artifacts archived if needed
-
docker compose … up -dcompleted without migrate errors -
/healthOK - Session still works
- Ingest smoke test passed
What if migrate errors show in Epure logs?
Stop retrying a half-applied schema. Restore the dump, check out the previous commit, compose up. Migrations run when the epure process starts, so there is no separate migrate container. Keep the dump off-box: Troubleshooting.
Why does login loop after an upgrade?
Cookie Secure flag mismatch. The prod overlay sets EPURE_SESSION_SECURE=1; local HTTP needs 0. Keep that value matched to HTTP vs HTTPS when you roll back, then confirm /health. See Configuration.
Can I roll back the schema with an older binary?
Only if you restore the pre-upgrade dump first, since schema moves forward only. --clean on pg_restore drops objects before restore. Confirm /health and login after compose up.
Do I drain Redis or workers?
No. Two containers, with no Redis stream and no worker fleet. Stop epure, restore Postgres if needed, compose up. Artifacts live on the artifacts_data volume if you uploaded maps.
I set EPURE_REGISTRATION=false but Register is still visible?
The running binary is current, but the clone is stale — or the container was not recreated after the env change. git pull, confirm EPURE_IMAGE=ghcr.io/epure-sh/epure:v0.1.7 (or newer), then docker compose up -d so Compose recreates epure. Configuration.
SDK ingest returns invalid_dsn after upgrade?
Pre-v0.1.5 required sentry_secret. Official Sentry SDKs send public-key-only auth. Pin v0.1.5, recreate, and use the DSN from Settings → SDK connection (http://PUBLIC_KEY@HOST/PROJECT_ID). Authentication.