Skip to main content
Run tai on your own infrastructure from the official container image. One image plays every server role; a Compose bundle deploys it, and the release pipeline signs and scans every artifact it publishes.

Quickstart

Deploy the Compose bundle against the official image.

Upgrades

Pull a new tag, run the migrations, recreate the app services.

Verify artifacts

Check cosign signatures and image digests.

Web stacks

Run the marketplace and website images.

Ops notes

Reverse proxies, backups, and health probes.

The image

docker.io/tai42/tai is the official image, mirrored at ghcr.io/tai42ai/tai. It is one minimal-core image that runs every deployment role from a single entrypoint (tai): the HTTP server, the task backend worker, and the metrics reader. What a container becomes is chosen by its command and its manifest, not by a different image per role. The three long-lived processes all come out of this one image:

Tags

The release publishes a semver fan-out — X.Y.Z, X.Y, X, and latest — for a stable release; a prerelease publishes its exact version tag only and leaves the moving tags on the last stable image. Pin an exact X.Y.Z tag in production; latest moves under you.

Minimum to run

  • A default database connection. POSTGRES_PASSWORD has no default — the stack refuses to start until it is set. It feeds the default database every core Postgres store binds to (TAI_DATABASE_DEFAULT_PG_*).
  • A Redis URL once any of these is on: access control, a registered task backend, more than one server worker, or config served from a non-file provider. The Compose bundle registers the arq backend and runs two workers, so it presets TAI_BUS_REDIS_URL (and the per-feature Redis URLs) for you.
  • Everything else has a working default — see the settings reference for every variable and its default.

What the image bundles

The image is the minimal core: the platform layers, the agents layer, and the baked reference providers — local storage, the arq task backend, the Redis identity (API-key) provider, and both sandbox providers — and the built Studio SPA. The bundled package set is exactly: The bundle ships a value for these bundled-plugin variables (a compose-file or env-template value; a value the operator must fill is shown as a placeholder): The two tai42-agents session images ship as digest placeholders the operator replaces with the released digests, and the operator sets exactly one of TAI_AGENTS_CLAUDE_API_KEY or the commented TAI_AGENTS_CLAUDE_OAUTH_TOKEN (the bundle ships neither). tai42-storage-local writes under STORAGE_LOCAL_ROOT_PATH, which defaults to ./templates resolved under the app’s working directory /app; the bundle’s example manifest selects the provider (storage_module: tai42_storage_local) and backs /app/templates with the tai-storage-local-data named volume, so stored files survive a container recreation. tai42-identity-redis presets nothing — it stays off until a manifest names it, then reads the shared TAI_DEFAULT_REDIS_URL. The two sandbox providers stay off until a manifest names one (sandbox_module); the variables above apply once a provider is selected. The bundle turns the docker sandbox’s egress-firewall readiness probe on for the session-creating services (SANDBOX_DOCKER_READINESS_PROBE_ENABLED on serve and backend), which has no effect until that provider is active. Every other plugin — the channels, the S3/GitHub storages, the celery/rq backends, the connectors, the webhook verifiers, monitoring, accounts, and the extra tools — is not baked in. Add the ones a deployment needs at runtime through the marketplace or by baking them into a derived image. See the layering for what each layer contains.
Runtime-installed plugins live in the server’s plugin prefix, not in the image. An image upgrade replaces the core but does not update a runtime-installed plugin — see Upgrades.

Reaching a service on the Compose network

A tool that fetches a URL server-side — the toolbox request tool, or any tool you write — passes tai’s URL guard before it connects. The guard is on by default and refuses private, loopback, and link-local addresses. Every service in the Compose bundle rides the default network, which takes a private Docker subnet, so such a tool cannot reach another Compose service until you allow that subnet in. To let a tool reach a service on the Compose network, set TAI_URL_GUARD_ALLOW_CIDRS to that network’s CIDR. It is an explicit opt-in — the guard blocks that range until you name it, and it bypasses nothing on its own. A run that only needs to reach the platform itself opens no network at all. The built-in door tools send_conversation_message and send_conversation_event submit a message or event back into a conversation in-process — no key, no HTTP request, and no URL guard.