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_PASSWORDhas no default — the stack refuses to start until it is set. It feeds thedefaultdatabase 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-
fileprovider. The Compose bundle registers the arq backend and runs two workers, so it presetsTAI_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 toolboxrequest 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.
