The tay image is the operational runtime with the optional web UI included.
It owns the Store and starts exactly one Tay Engine. It also exposes
the same Executor Protocol v1 Unix socket as the headless image, so external
workers connect in the same way.
browser -> HTTP :4000 -> Phoenix LiveView -> Tay public API
|
worker -> /run/tay/tay.sock -> Executor API -> Engine -> /var/lib/tay/storeIt is not a dashboard sidecar. Set TAY_ENABLE_DASHBOARD=true on the one Tay
container that owns /var/lib/tay; Tay is deliberately single-writer.
Compose quick start
The repository example starts the dashboard-enabled runtime. A local Python
socket worker is available through the local-worker profile:
TAY_ENABLE_DASHBOARD=true docker compose up --build
Open http://localhost:4000/tay. The example binds HTTP to host loopback and
does not enable application-level authentication.
Set TAY_DASHBOARD_HTTP_PORT to change only the published host port in this
Compose example; the container continues listening on port 4000.
TAY_DASHBOARD_SECRET_KEY_BASE remains required because Phoenix uses it to
sign browser sessions. Supply a random value without editing the Compose file:
export TAY_DASHBOARD_SECRET_KEY_BASE="$(openssl rand -base64 48)"
TAY_ENABLE_DASHBOARD=true docker compose up -d
To additionally enable built-in HTTP Basic authentication, provide both credentials:
export TAY_DASHBOARD_USERNAME=operator
export TAY_DASHBOARD_PASSWORD='replace-with-a-long-random-password'
TAY_ENABLE_DASHBOARD=true docker compose up -d
Pin TAY_IMAGE to an immutable release tag in production. Local workers can
share the taysocket volume; remote workers use the mTLS HTTP endpoint.
Run without Compose
Create the two volumes once:
docker volume create taydata
docker volume create taysocket
Then start the release:
docker run --name tay \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid,size=64m,uid=10001,gid=10001,mode=0700 \
--cap-drop ALL \
--security-opt no-new-privileges \
-p 127.0.0.1:4000:4000 \
-e TAY_DATA_DIR=/var/lib/tay/store \
-e TAY_INITIALIZE_IF_MISSING=true \
-e TAY_ENABLE_DASHBOARD=true \
-e TAY_DASHBOARD_SECRET_KEY_BASE='replace-with-at-least-64-random-bytes------------------------' \
-v taydata:/var/lib/tay \
-v taysocket:/run/tay \
ghcr.io/andriisydorenko1904/tay:1.3.1
On subsequent starts, set TAY_INITIALIZE_IF_MISSING=false. Initialization is
only for a genuinely missing Store and is never a repair operation.
Configuration
The image accepts the runtime and dashboard settings below. The Bandit API's
TAY_HTTP_* and capacity settings are listed in the
standalone configuration reference.
| Variable | Default | Required | Meaning |
|---|---|---|---|
TAY_DATA_DIR | /var/lib/tay | no | Authoritative Store root. Use /var/lib/tay/store with a named volume. |
TAY_SOCKET_PATH | /run/tay/tay.sock | no | Executor Protocol v1 Unix socket. |
TAY_INITIALIZE_IF_MISSING | false | no | Initialize only a genuinely absent Store. |
TAY_DEFAULT_QUEUE_CONCURRENCY | 10 | no | Maximum concurrently executing jobs in the standalone default queue (1..65536). |
TAY_CALLER_TIMEOUT_MS | 5000 | no | Engine call timeout in milliseconds; submitted timeouts have an unknown outcome and require same-ID reconciliation. |
TAY_GROUP_COMMIT_INTERVAL_MS | 0 | no | Strict-durability enqueue batching window (0..1000 ms); invalid values fail startup. |
TAY_CHECKPOINT_INTERVAL_MS | 60000 | no | Crash-safe Store-v2 semantic checkpoint interval (0..4294967295 ms); 0 disables it. |
TAY_TERMINAL_RETENTION | 24h | no | Initial terminal retention such as 30m, 1h, 24h, or 7d. Dashboard/API zero is a one-shot full terminal-history purge and persists 1h afterward. A retention saved by successful Dashboard compaction takes priority on restart. |
TAY_ENABLE_DASHBOARD | false | no | Enable the bundled HTTP dashboard. |
TAY_DASHBOARD_HOST | localhost | no | Public hostname accepted for LiveView origin checks; no scheme, port, or path. |
TAY_DASHBOARD_PORT | 4000 | no | Container HTTP listen port. |
TAY_DASHBOARD_USERNAME | none | no | Optional HTTP Basic authentication username; must be paired with the password. |
TAY_DASHBOARD_PASSWORD | none | no | Optional HTTP Basic authentication password; must be paired with the username. |
TAY_DASHBOARD_SECRET_KEY_BASE | none | when enabled | Random Phoenix signing secret of at least 64 bytes. |
Basic Auth is disabled when neither credential is set. Supplying only one, or
supplying a blank value, fails startup. Other invalid or missing required
configuration also fails startup. The HTTP listener binds all container
interfaces so Docker port publishing works;
TAY_DASHBOARD_HOST controls URL generation and LiveView origin validation,
not the bind address.
If users access the UI as https://jobs.example.com/tay, set
TAY_DASHBOARD_HOST=jobs.example.com. Keep the internal port at 4000 and let
the reverse proxy terminate TLS. For nonstandard public ports, configure the
proxy to preserve the browser Host header.
Security boundary
The dashboard can display job arguments and perform Retry, Cancel, Pause, and
Resume operations. Treat network access to it as administrator access. The
default security boundary is the deployment network: the image publishes no
port by itself, and the Compose example binds HTTP only to 127.0.0.1.
- Bind to
127.0.0.1when accessing it locally. - For remote access, prefer a private network, VPN, SSH tunnel, or trusted ingress. Terminate TLS before traffic crosses an untrusted network.
- Enable the built-in Basic Auth when deployment-level access control is not sufficient or when an additional protection layer is desired.
- Store the Phoenix secret and any optional credentials in the platform secret manager. Do not reuse the signing secret as the dashboard password.
The embedded Hex package intentionally does not impose authentication because the host Phoenix application owns its identity and authorization policy.
Persistence, health, and upgrades
/var/lib/tay is durable state; /run/tay is ephemeral worker IPC. Deleting
the socket volume is safe while Tay and workers are stopped. Deleting the data
volume deletes job history.
The OCI health check succeeds only after the Engine is ready and the selected transport accepts connections. The container smoke test separately exercises the default unauthenticated HTTP page and its LiveView assets; host tests cover the optional Basic Auth path. Startup has a 15-minute health-check grace period to match Tay's bounded recovery deadline; this does not weaken steady-state health checks.
Use the same cold backup and restore process as the headless runtime. Stop the old container before starting a new image against its volume. Never use a rolling deployment with two replicas sharing the Store.
Choosing a mode
Use tay:<version> without TAY_ENABLE_DASHBOARD for headless operation, or set
TAY_ENABLE_DASHBOARD=true when the official UI is needed. In an existing Phoenix
application, mount the dashboard included in the tay Hex package instead of the standalone web
host.