Skip to main content

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​

  1. Back up the database. The data lives in the postgres-data named volume, backed up with pg_dump (there is no usage.db file anymore):

    docker compose exec postgres pg_dump -U ace ace > openace_backup_$(date +%Y%m%d).sql

    Adjust -U <DB_USER> and the database name if you changed DB_USER / DB_NAME in .env. See DATABASE_BACKUP.md for scheduled backup strategies.

  2. Know your secrets. SECRET_KEY, OPENACE_ENCRYPTION_KEY, and DB_PASSWORD in .env must survive the upgrade unchanged (see Secret Key Compatibility).

  3. 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_23 or any later revision on the supported migration chain, scripts/check_min_revision.py lets the container start and alembic upgrade head applies 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.py errors out and blocks container startup, refusing to run on an unsupported migration path.
  • Fresh databases (no alembic_version table) 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​

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:

  1. Waits for PostgreSQL to be ready
  2. Checks whether the application schema already exists
  3. Runs scripts/check_min_revision.py to verify the current revision is on the supported migration chain (fresh databases pass automatically)
  4. Runs alembic upgrade head
  5. 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.py failure — the database revision predates baseline_2026_06_23. Restore from a healthy backup on the supported chain; there is no in-place path from ancient revisions.
  • alembic upgrade head failure — the entrypoint logs ERROR: 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:

  1. Pin the previous image in .env (e.g. IMAGE_NAME=openace/open-ace:v1.2.0 for the version you ran before).

  2. Restore the database from the pre-upgrade backup:

    docker compose down
    cat openace_backup_YYYYMMDD.sql | docker compose run --rm postgres psql -U ace -d ace
    docker compose up -d

    Restore into a clean database when practical (drop and recreate, or restore into the volume) rather than replaying over a newer schema.

  3. Revert .env changes made for the new version (for example, newly required variables) and restart.

Notes:

  • Downgrading migrations with alembic downgrade is 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; only docker compose down -v or explicit docker volume rm deletes data.
  • If the new version rotated any secrets (you should not rotate during an upgrade), revert .env to the pre-upgrade values as part of rollback.

Secret Key Compatibility​

  • Carry SECRET_KEY, OPENACE_ENCRYPTION_KEY, and DB_PASSWORD over unchanged when upgrading. A new OPENACE_ENCRYPTION_KEY that 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_KEY to the same value previously used for SECRET_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_KEYS data-key registry are documented in KEY_MANAGEMENT.md.

Post-Upgrade Verification​

  • docker compose ps shows open-ace (and postgres) healthy; the healthcheck probes /readyz
  • docker compose logs open-ace shows 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