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
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
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.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:
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:

