Upgrading
This guide covers upgrading Open ACE: preparation and backup, the upgrade procedure, database migration failure handling, and rollback. Replacing the application image never touches your data — all state lives in named volumes (postgres-data, config-data, workspace-data, agent-state).
Table of Contents
- Before You Upgrade
- Minimum Upgrade Baseline
- Upgrade Steps
- Migration Failure Handling
- Rollback
- Secret Key Compatibility
- Post-Upgrade Verification
Before You Upgrade
-
Back up the database. The data lives in the
postgres-datanamed volume, backed up withpg_dump(there is nousage.dbfile anymore):docker compose exec postgres pg_dump -U ace ace > openace_backup_$(date +%Y%m%d).sqlAdjust
-U <DB_USER>and the database name if you changedDB_USER/DB_NAMEin.env. See DATABASE_BACKUP.md for scheduled backup strategies. -
Know your secrets.
SECRET_KEY,OPENACE_ENCRYPTION_KEY, andDB_PASSWORDin.envmust survive the upgrade unchanged (see Secret Key Compatibility). -
Pick the target version. By default Compose tracks
openace/open-ace:latest; for controlled upgrades, pin a version tag in.env:# Pin a specific version (in .env)echo "IMAGE_NAME=openace/open-ace:v1.2.0" >> .env
Minimum Upgrade Baseline
The minimum supported upgrade starting point is baseline_2026_06_23.
- If the database is at
baseline_2026_06_23or any later revision on the supported migration chain,scripts/check_min_revision.pylets the container start andalembic upgrade headapplies the missing migrations automatically. - If the database still sits on a revision from before the baseline (e.g., a historical hash revision),
check_min_revision.pyerrors out and blocks container startup, refusing to run on an unsupported migration path. - Fresh databases (no
alembic_versiontable) are allowed through in development mode; production mode requires an explicit migration before startup.
Such a failure means the database has drifted off the supported migration chain: restore from a known-healthy backup that is already on the baseline_2026_06_23 chain, then upgrade. Do not keep retrying against the stale revision.
Upgrade Steps
Docker Compose (recommended)
cd /path/to/open-ace
# 1. Back up (see Before You Upgrade)
# 2. Pull the new image
docker compose pull
# 3. Recreate the containers
docker compose up -d
# 4. Watch the startup and automatic migration
docker compose logs -f open-ace
On first start after the image change, docker-entrypoint.sh automatically:
- Waits for PostgreSQL to be ready
- Checks whether the application schema already exists
- Runs
scripts/check_min_revision.pyto verify the current revision is on the supported migration chain (fresh databases pass automatically) - Runs
alembic upgrade head - Creates the default admin account on a fresh database
To run the check and migration manually:
docker compose exec open-ace sh -c 'python3 scripts/check_min_revision.py && alembic upgrade head'
With the scheduler profile or the multi-user overlay, upgrade the whole stack the same way (for multi-user: docker compose -f docker-compose.yml -f docker-compose.multi-user.yml up -d).
Bare metal (package / source installs)
# Back up first, then:
git pull
# Run database migrations
alembic upgrade head
# Restart the service
python3 scripts/manage.py stop
python3 scripts/manage.py start
# or, for a systemd installation:
sudo systemctl restart open-ace
Package-method installs reuse install.sh, which detects the existing installation and prompts to upgrade; it also runs check_min_revision.py before migrating and refuses on pre-baseline databases.
Offline servers
On a connected machine, export the new images and transfer them:
./scripts/install-central/docker-method/export-image.sh --build --compress
# Copy open-ace-images.tar.gz to the server, then:
gunzip -c open-ace-images.tar.gz | docker load
docker compose up -d
scripts/install-central/docker-method/upgrade-remote.sh automates the remote upgrade flow.
Migration Failure Handling
If startup fails during the migration step:
docker compose logs open-ace
check_min_revision.pyfailure — the database revision predatesbaseline_2026_06_23. Restore from a healthy backup on the supported chain; there is no in-place path from ancient revisions.alembic upgrade headfailure — the entrypoint logsERROR: alembic upgrade head failed. Keep the failed container stopped, inspect the log for the failing migration, fix the reported cause (disk space, connectivity to PostgreSQL, interrupted previous migration), and start again. Alembic applies migrations transactionally per migration file.- After any manual database surgery, re-run the verification command above before letting the service serve traffic.
Do not run two versions of the application against a half-migrated database: runtime schema checks (schema_guard.py) use a stricter require-head policy than the install-time check and will refuse to start a service on a not-fully-migrated database.
Rollback
Rolling back is image pinning plus database restore:
-
Pin the previous image in
.env(e.g.IMAGE_NAME=openace/open-ace:v1.2.0for the version you ran before). -
Restore the database from the pre-upgrade backup:
docker compose downcat openace_backup_YYYYMMDD.sql | docker compose run --rm postgres psql -U ace -d acedocker compose up -dRestore into a clean database when practical (drop and recreate, or restore into the volume) rather than replaying over a newer schema.
-
Revert
.envchanges made for the new version (for example, newly required variables) and restart.
Notes:
- Downgrading migrations with
alembic downgradeis not a supported rollback path — schema downgrades are not maintained. Always roll the data back from a backup. - Named volumes are preserved by
docker compose down; onlydocker compose down -vor explicitdocker volume rmdeletes data. - If the new version rotated any secrets (you should not rotate during an upgrade), revert
.envto the pre-upgrade values as part of rollback.
Secret Key Compatibility
- Carry
SECRET_KEY,OPENACE_ENCRYPTION_KEY, andDB_PASSWORDover unchanged when upgrading. A newOPENACE_ENCRYPTION_KEYthat does not match the old one leaves every stored secret (SSO client secrets, SMTP passwords, API keys, integration credentials) permanently undecryptable. - Historical note for deployments that predate the split between session signing and secret encryption: before upgrading an existing deployment that already stores encrypted secrets, set
OPENACE_ENCRYPTION_KEYto the same value previously used forSECRET_KEY; after the upgraded service proves it can read existing secrets, rotate to a dedicated key during a planned maintenance window. - Full rotation procedures, the eight encrypted stores covered by one key, and the
OPENACE_ENCRYPTION_KEYSdata-key registry are documented in KEY_MANAGEMENT.md.
Post-Upgrade Verification
-
docker compose psshowsopen-ace(andpostgres) healthy; the healthcheck probes/readyz -
docker compose logs open-aceshows the migration completed and the service listening on 19888 - Login works; existing users, sessions, and configuration are intact
- Workspaces and integrations (SSO, SMTP, DingTalk/Feishu, webhooks) still authenticate — this also proves the encryption key carried over correctly
- Archive or remove the database backup after verification