Skip to main content
Bring up the whole stack — serve, the backend worker, metrics, Postgres, and Redis — with the Compose bundle from tai-distribution, running the official image. The bundle needs Docker Compose 2.20 or newer.

Boot the bundle

1

Get the bundle

2

Pin the image and set the secrets

Set POSTGRES_PASSWORD (it has no default — Compose refuses to start until it is set), and pin the image to a release rather than running latest:
TAI_VERSION in .env
3

Create the config directory

config/ bind-mounts at /app, so config/manifest.yml is the manifest the runtime loads and config/.env is the app-side environment. Create config/.env even when it is empty — the config-reload path treats a missing file as an error.
4

Start it

A one-shot db-migrate runs tai db migrate first; serve and backend wait for it before they start. Only serve publishes a port (${TAI_SERVE_PORT:-8000}) — Postgres and Redis stay on the Compose network.
.env.example ships ACCESS_CONTROL_ENABLE=false — the auth-free quickstart shape, every route open. Turn it on before anything but a laptop, and register an identity provider in the same change: with access control on and no provider, the runtime refuses to boot. See Turn on access control.

The persistent mounts

Three paths a real deployment must keep across a container recreation, each located by an env var the server reads: The bundle bind-mounts config/ for the first and backs /app/templates with the tai-storage-local-data named volume for the third. Give the plugin prefix its own persistent volume the same way, or a marketplace install lands in the image’s ephemeral venv and is lost when the container is replaced. Persist all three, or a recreated container loses stored files or boots with the code and its registration out of sync. The bundled Postgres and Redis keep their own named data volumes. See Add plugins for the two ways a deployment installs plugins onto these mounts.

Profiles

The core stack is arq-on-Redis, and the example manifest selects local storage (storage_module: tai42_storage_local). Three opt-in profiles add infrastructure for plugins that are not in the minimal image — add the plugin (a derived image or a marketplace install) before enabling its profile:
Langfuse tracing runs as its own stack from compose/langfuse/ and likewise needs the tai42-monitoring-langfuse plugin added — see Monitoring with Langfuse.

Build the image from source (dev only)

For running the stack against uncommitted local changes, compose/docker-compose.local.yml layers a SOURCE=local build onto every app service, building from sibling checkouts instead of pulling the release:
The source build’s siblings context is the parent of the checkouts, which can hold untracked secrets. Run it on a local builder only — never CI, never a shared registry. Production runs the official image.

See also

  • Deploy — transports, workers, and the serving modes.
  • Operate — access control, plugin setup, and the fleet view.
  • Upgrades — moving to a new image tag.