Upgrades & Rollbacks
How releases are versioned, how to upgrade a self-hosted instance safely, and how to roll back if something goes wrong.
1. How Versions Work
OpenPay follows semantic versioning. Every release is a git tag of the form vMAJOR.MINOR.PATCH:
| Bump | Example | When it happens |
|---|---|---|
| Major | v1.4.2 → v2.0.0 | Breaking changes: schema migrations, config/API incompatibility, different deployment layout |
| Minor | v1.4.2 → v1.5.0 | New features, additive changes (new endpoints, new services, optional config) |
| Patch | v1.4.2 → v1.4.3 | Bug fixes, security patches, no behavior/API change |
A patch is always a drop-in upgrade — pull and restart, no other action. A minor may add features behind optional config. A major can require migrations and manual steps, so the release notes always spell them out before the upgrade instructions.
Before every upgrade: check the release notes (see the Changelog) for the version you're targeting. Major versions in particular may document manual steps the upgrade script cannot automate.
2. What an Upgrade Does
The upgrade tooling is semi-automated: it never touches containers on its own and always keeps a way back. The flow is:
- 1Pre-flight — Checks Docker, the git repo, and that the current stack is healthy.
- 2Backup — Snapshots PostgreSQL (logical dump) plus the postgres/redis/nats named volumes into .backups/.
- 3Checkout — Switches the repo to the target release tag and validates the new docker-compose.yml.
- 4Migration guard — Runs Hyperswitch DB migrations automatically — but only when the router image version changed.
- 5Apply — Pulls images and starts the stack.
- 6Verify — Waits for core services to report healthy.
- 7Auto-rollback — If anything fails after the backup point, restores the previous version and data automatically.
You are never left mid-upgrade: the previous version and its data snapshot are recorded in .openpay-state/state before the switch, so a rollback is always one command away.
3. Run an Upgrade
make upgrade
# or pin a specific version:
make upgrade TARGET=v1.5.0
# the scripts are also callable directly:
./scripts/upgrade.sh # latest
./scripts/upgrade.sh v1.5.0 # pinned
./scripts/upgrade.sh --dry-run # print the plan, change nothingFlags
| Flag | Meaning |
|---|---|
--skip-backup | Skip the backup step. Not recommended for major/minor upgrades. |
--skip-migrations | Do not run the migration guard, even if the router image changed. |
--skip-rollback | Never auto-rollback; on failure the script stops and you roll back manually. |
--dry-run | Print the full plan (from/to, backup, migrations, rollback) and exit. |
4. Backups
Backups live in .backups/<version>-<timestamp>/ (override the root with OPENPAY_BACKUP_DIR). Each backup contains:
postgres-dumpall.sql— a portable logical dump of every database.postgres-data.tgz,redis-data.tgz,nats-data.tgz— exact named-volume snapshots used for restore.MANIFEST.txt— version, timestamp, and file listing.
make backup
./scripts/backup.sh --label before-v2.0.0Off-box copies: backups are plain files, so copy the directory somewhere outside the server before upgrading — the upgrade will not touch them, but a disk failure would.
5. Rollback
Rollback stops the stack, checks out the previous release, restores the volume snapshots from the pre-upgrade backup, and starts again. Schedule a short maintenance window — the stack is down during the restore.
make rollback
./scripts/rollback.sh # uses the recorded state
./scripts/rollback.sh --to v1.4.2 --backup .backups/v1.4.2-20260726-140000 --yes
# flags: --to <version> --backup <dir> --yes (skip confirmation)If the stack is unhealthy right now (e.g. a failed upgrade left it broken), run the rollback first — it does not require a healthy stack, only the Postgres volume present.
6. Health Checks
The upgrade script gates on service health before and after the switch. Run the check standalone to diagnose a deployment:
./scripts/health-check.sh # immediate
./scripts/health-check.sh --wait # wait up to 120s for healthCore services (postgres, redis, nats, hyperswitch, killbill) must be healthy. Profile-gated services (proxy, control center, Tazama, monitoring) warn but never block an upgrade.
Production Deploy
Hardening guide for live environments
Monitoring & Grafana
Dashboards, logs, and alerts