Skip to main content
Upgrading pulls new container images and lets the backend apply any pending Postgres schema migrations automatically. Back up your database first: there’s no rollback path once a migration has run.

Before you upgrade

Take a Postgres backup before you upgrade. See Back up and restore Postgres in Troubleshooting for the commands.There is no documented rollback path for a schema migration once it has run. If an upgrade causes a problem, restoring from your backup is the only recovery path.

One-time: the Compose project is now named tessary

This applies once, to installations created before this release. If you install for the first time from this release onward, skip this section.The Compose project name changed from evals-platform to tessary. Docker derives volume, container and network names from the project name, so the new stack looks for volumes that do not exist yet and creates them empty. Started without one of the two remedies below, the backend comes up against an empty database and Caddy reissues your TLS certificates.
Three volumes are project-prefixed and therefore change name: tessary-sandbox-work is unaffected: it carries an explicit name in the configuration and was never project-prefixed. Containers are renamed too (evals-platform-postgres-1 becomes tessary-postgres-1), and so is the network (evals-platform_evals becomes tessary_tessary — the project prefix changed in that release, the evals half in this one). If you set POSTGRES_DATA_DIR to a host path, your database is on that path and none of this touches it — but Caddy’s two volumes still move. Pick one of these two. Do it before the first docker compose up on the new configuration.

Option A — keep the old project name

Nothing moves. Name the old project explicitly on every command from now on:
-p outranks the project name pinned in the configuration. This is the smaller change and it is a valid end state, not just a delay — but every command needs the flag, and the documentation elsewhere assumes -p tessary.

Option B — copy the volumes to the new names

Do this with the stack stopped, so nothing is writing while the copy runs.
Then start the stack normally — docker compose -f oci://docker.io/tessaryai/tessary:compose up -d -y — and confirm with docker compose -p tessary ps that every service is healthy and your existing projects and traces are still there. This copies rather than moves, so the old volumes are still on disk if something is wrong. Remove them only once you are satisfied:

If you imported our Grafana dashboards

The three dashboards and the alert rules under observability/ changed identity in the same release: their uids are now tessary-overview, tessary-ingest and tessary-cpu, the Grafana folder they expect is tessary, and every panel query selects service_name="tessary-backend" instead of service_name="evals-platform-backend". Nothing in a running Grafana renames itself when the files change. Create the tessary folder first — the alert-rule import fails outright if it does not already exist — then re-import all three dashboards and the alert rules. The old dashboards keep their old uids and their annotation history; delete them when you are ready. Metric and log series recorded before the upgrade carry the old service_name, and renaming a query does not go back and rename the data. Panels will show history stopping at the upgrade and starting again under the new name. If you need continuity across your retention window, widen the selector to a regex over both names — service_name=~"(evals-platform|tessary)-backend" — and narrow it back once the old data has aged out. Otherwise the split is simply the cost, and is the trade this rename accepted.

One-time: EVALS_ settings are now TESSARY_

This applies once, to installations created before this release. There is no fallback: the backend ignores every EVALS_* variable. A variable you do not rename reverts to its default, and TESSARY_JDBC_URL reverting to blank stops the boot.
Every environment variable that started with EVALS_ now starts with TESSARY_. The rest of each name is unchanged, so the rename is mechanical:
These are the ones a self-hosted install normally sets: SITE_DOMAIN, TLS_MODE and ACME_EMAIL never carried the prefix and do not change. The matching YAML keys moved too, from evals.* to tessary.*, and so did the logger name: logging.level.ai.tessary.evals is now logging.level.ai.tessary. You only need either if you mount your own application.yaml instead of setting environment variables. The table above lists the settings a self-hosted install normally sets, not every key that exists. The rule is what matters: if it started with EVALS_, it starts with TESSARY_ now.

One-time: the database is now named tessary

This applies once, to installations created before this release, and only if you let POSTGRES_DB, POSTGRES_USER and POSTGRES_PASSWORD take their defaults.
The three defaults changed from evals to tessary. Postgres does not rename an existing database to match, so a stack started on the new defaults finds nothing and initialises an empty one. Pin the old names. This is one edit, it cannot half-apply, and nothing else about your install changes. Put these in .env:

If you would rather rename the database and role

You do not need to. Do this only if you want the names on disk to match the new defaults. Postgres refuses to rename the role you are connected as, so the rename needs a temporary superuser to run from. Stop the stack except for Postgres, then run all six commands:
Renaming a role clears its stored password, so the fifth command is required, not optional. Set a password of your own rather than tessary if the database port is published or the host is shared.

One-time: everyone is signed out once

The session cookie is now tessary-session, so existing sessions stop resolving and everyone signs in again. Nothing else is affected: accounts, API tokens and org membership are untouched. API tokens do not change. They are minted as tsy_<scope>_… and always have been; that prefix is not part of this rename.

How migrations work

Postgres schema migrations run automatically through Liquibase when the backend container starts. There’s no separate migrate command to run, and no cloud account or external migration tool is involved.

Upgrade steps

1

Re-run the install command

The compose tag always resolves to the current release, and the configuration behind it pins that release’s images, so this one command fetches the new configuration and the new images together. Docker recreates any container whose image changed. The backend applies any new schema migrations during that boot, before it starts serving traffic.From a clone, the equivalent is git pull && docker compose pull && docker compose up -d.
Containers are running on the new images, and the backend is serving traffic again. Check with docker compose -p tessary ps.
A configuration published from a registry can never be older than the images it names: every release publishes both, and the configuration carries that release’s version as its own default. Pin a release by naming it — oci://docker.io/tessaryai/tessary:compose-<version>, for a published release version — and upgrade by dropping back to the compose tag.
Your data is in named volumes (tessary-postgres-data, tessary-sandbox-work), so it survives a recreate. Only docker compose -p tessary down -v removes it.

Preserve TLS certificate state

Preserve the Caddy certificate-state volumes across the upgrade. If they’re removed or recreated, Caddy reissues TLS certificates unnecessarily.

What isn’t supported yet

Self-hosted upgrades don’t currently have a documented maintenance-window requirement, a blue-green deployment mechanism, or a downgrade path. If an upgrade needs to be reverted, restore from the Postgres backup you took before upgrading.