Compatibility

Back up before the schema moves.

Use exact release identity, inspect state, and pair rollback binaries with the state they understand.

Moving an existing installation

Releases and images now come from github.com/kayiik/llm-gateway and ghcr.io/kayiik/llm-gateway. Release numbering restarted with the move, so builds from before it carry higher version numbers than current releases: take the current one from the latest release, not by comparing numbers.

State, keys and credentials carry over unchanged. The optional companion daemon is no longer paired through environment variables: add it as an extension after the upgrade, as companion daemon extensions describes. Follow the upgrade for your installation below, offline backup included, and remove LLMGW_PROVIDER_ROSTER_URL wherever it points at a previous feed, such as the environment, .env or deploy/.env. Take deploy/docker-compose.prod.yml from a current checkout too, because one from before the move defaults to a previous feed. The built-in default names the current feed.

The provider roster's revisions restarted with the move. Current releases record which feed their roster cache came from, and replace a cache written for another feed on their next refresh, so the cache needs no cleanup. If the provider roster reports "Roster rollback or conflicting revision rejected." after the move, the release predates this: update to the latest release.

Before an upgrade

  1. Schedule maintenance, drain traffic, and stop all gateway writers.
  2. Check the installed binary's llmgw --help and use its built-in backup if it lists one; otherwise snapshot the entire stopped state volume, including SQLite WAL/SHM, configuration, secrets, and caches.
  3. Record the image digest or binary checksum.
  4. Retain the original encryption key, deployment environment, state mounts and configured external config/database/cache paths.
  5. Read the release notes and test extraction into a separate location.

Keep the original snapshot unchanged outside automatic retention. Do not start the new binary on original state just to make a backup. The operations runbook covers backups and rollback.

Standalone image installation

Use this for the published-image quickstart, which pins an exact image version, ghcr.io/kayiik/llm-gateway:<VERSION>. Select the next one from release notes.

  1. Complete the offline backup checklist using the installed image. Keep the original snapshot outside the volume and automatic retention.
  2. Preserve your installation folder, compose.yaml, .env, project name and state:/state volume. Keep the original administrator and encryption keys; do not generate replacements. Remove stale shell overrides.
  3. Change only image: in compose.yaml to the selected published version/digest.
  4. From that same folder, in POSIX or PowerShell:
standalone installation · after backup
docker compose pull gateway
docker compose up -d gateway

No clone, --build, override file or LLMGW_IMAGE variable is involved. Compose reads the same .env automatically. Check startup logs, running version, health, authenticated administrator state and intended provider access before restoring traffic. Keep the prior image and snapshot until acceptance.

Native binary installation

After the same offline backup, download and verify the replacement archive. Stop the old process before replacing its executable. Run llmgw serve (or .\llmgw.exe serve) with the saved keys and the same absolute state/config paths, not a maintenance user's default ~/.llmgw. Preserve the old binary and original snapshot together.

Production Compose deployment

The TLS starting point in deploy/ runs the image that LLMGW_IMAGE names; Compose stops with an error while it is unset. After the same offline backup, keep the Compose project, deploy/.env, state directory and any private overrides, and record the current LLMGW_IMAGE value for rollback. Change only that value in deploy/.env to the selected published version/digest, then from the repository root:

repository root · production Compose
docker compose -f deploy/docker-compose.prod.yml pull gateway
docker compose -f deploy/docker-compose.prod.yml up -d gateway

Check the running version and run deploy/smoke.sh before restoring traffic. Rollback restores the snapshot and the recorded image.

Developers: source installation

For the root source Compose recipe, back up offline, select the intended source tag in the same clone, and preserve its private .env, config.local.yaml, project and llmgw-state volume. Do not overwrite config with the example. Use LLMGW_HOST_PORT=127.0.0.1:8787, not standalone LLMGW_PORT, and clear stale shell overrides before rebuilding:

repository root · source build only
docker compose --env-file .env up -d --build

Companion daemon extensions

The gateway no longer reads LLMGW_EXTENSION_URL or LLMGW_EXTENSION_SECRET. The optional companion daemon, which serves GitHub Copilot, OpenAI Codex, Google Antigravity, Edge TTS, anonymous OpenCode Zen and Anthropic setup tokens, is added as an extension instead: an address and a shared secret that the gateway stores encrypted. Until it is added, the providers it serves report that no extension serves them, and while either variable is still set the gateway logs a startup warning.

An installation that used the daemon, after the offline backup and the upgrade above:

  1. Note the two values; an unset LLMGW_EXTENSION_URL meant http://127.0.0.1:18888. Then remove both variables wherever they are set: the environment, .env, deploy/.env, and any Compose file that passes them through.
  2. Keep LLMGW_CREDENTIAL_ENCRYPTION_KEY set; the gateway stores the secret only encrypted.
  3. Add the daemon on the console's Providers page, under Extensions → Add extension, with that address and secret, or with POST /admin/api/extensions and a JSON body with its name, url and secret.
  4. Upgrade the daemon to the release that the gateway's release notes name. The console marks an older daemon Update needed.

With one extension, every provider the daemon serves uses it. With several, each provider names the extension that serves it, and adding a second extension keeps the existing providers with the first. A rollback to a release from before extensions needs the two variables again.

Current compatibility aliases

DeprecatedReplacement
categories:endpoints:
/admin/api/categories/admin/api/endpoints
categories state keyendpoints
supported_endpointssupported_surfaces

No removal release is scheduled. Endpoint pseudo-model rows already use owned_by: "endpoint", not "category".

State migration

Applicable legacy keys, usage, credential structures, and bindings migrate idempotently. Incompatible catalog cache entries are discarded and rediscovered. Existing encrypted system connections are not overwritten by config seeding.

Restore rejects a backup schema newer than the running binary, and the binary refuses to open a database that a newer release has migrated.

Rollback

Restore the original pre-upgrade snapshot into an empty replacement volume/directory, including original WAL and external state, ownership/permissions, environment and encryption key. Never overlay migrated state or run the old image against the migrated database. There is no supported database downgrade.

Run the matching prior binary or image by exact version/digest, then verify health, authenticated admin state, models and a small completion for each intended credential scope. Rollback discards writes made after the snapshot. See the recovery checklist.