Docker Compose
The standalone bundle runs Tayga with ClickHouse and Redpanda on one Docker host, and nothing else: no demo services. Your services, or your OpenTelemetry Collector, send OTLP to it. The bundle lives in the repository under deploy/standalone/, and each release attaches it as tayga-standalone-<version>.tar.gz.
What runs
Section titled “What runs”| Service | What it does | Published on the host |
|---|---|---|
tayga-ingest |
OTLP receiver: gRPC on 4317, HTTP on 4318 (/v1/traces, /v1/logs) |
TAYGA_OTLP_GRPC_PORT (4317), TAYGA_OTLP_HTTP_PORT (4318) |
tayga-api |
Web app and JSON API (/healthz, /metrics, /api/v1/…) |
TAYGA_HTTP_PORT (8090) |
tayga-writer, tayga-assembler, tayga-logminer, tayga-notifier |
Raw storage, error stories, log templates and alerts, alert delivery | no |
tayga-migrate |
One-shot ClickHouse schema migration; the services above wait for it | no |
clickhouse |
clickhouse/clickhouse-server, volume clickhouse-data |
no |
redpanda |
redpandadata/redpanda:v26.2.3, one broker in dev-container mode, volume redpanda-data |
no |
The Tayga image is ghcr.io/softberries/tayga, pinned through TAYGA_VERSION. Every Tayga container runs as an unprivileged user (uid 10001).
Requirements. Docker with the Compose v2 plugin, and disk for ClickHouse (raw spans and logs are kept 3 days). Redpanda may use up to REDPANDA_MEMORY (1 GB by default). With a little test traffic the whole stack used about 1.2 GB of memory: ClickHouse about 950 MB, Redpanda about 220 MB, each Tayga service under 10 MB (docker stats, 2026-10-07, Docker Desktop on Apple silicon). Real traffic needs more; see Retention and disk for sizing.
Install with the installer
Section titled “Install with the installer”curl -fsSL https://raw.githubusercontent.com/softberries/tayga/master/scripts/install.sh | shThe installer:
- checks that Docker and Compose are there and that the ports are free (it stops before creating anything if one is taken);
- downloads the bundle of the release you ask for (the latest by default) and verifies it against its published SHA-256 checksum, or, with
--local, uses your checkout; - writes the settings it manages into
<dir>/.env, starts the stack, waits up to 300 seconds fortayga-apito report healthy, and prints the URLs and a Collector snippet.
Installer options
Section titled “Installer options”Pass options after sh -s -- when you pipe the script, or directly when you run a copy:
curl -fsSL https://raw.githubusercontent.com/softberries/tayga/master/scripts/install.sh | sh -s -- --version 0.1.0 --dir ~/tayga| Option | Meaning |
|---|---|
--version V |
Release to install (0.1.0 or v0.1.0). Default: the latest release. |
--dir DIR |
Install directory. Default: $TAYGA_DIR, else ~/tayga. |
--project NAME |
Compose project name, default tayga (kept in DIR/.env). It prefixes the containers, the network (tayga_default) and the volumes. |
--ports N |
Adds N to every published port: --ports 10000 gives 18090, 14317 and 14318. |
--bind ADDR |
Address the published ports bind to. Default 127.0.0.1 (this machine only); 0.0.0.0 exposes them on every interface. Read Exposing the ports first. |
--local |
Use this checkout’s deploy/standalone and a locally built image (tayga:local, built from docker/Dockerfile if missing) instead of downloading a release. |
--uninstall |
Stop and remove the stack’s containers and network. Keeps the data volumes and DIR, so a later install picks the data up again. |
--purge |
With --uninstall: also delete the data volumes and the files the installer put in DIR (DIR itself goes when nothing else is left in it). |
-h, --help |
Show the help. |
| Environment variable | Meaning |
|---|---|
TAYGA_DIR |
Default for --dir. |
TAYGA_IMAGE |
With --local: the image to use (default tayga:local). |
TAYGA_DOWNLOAD_BASE |
Base URL of the release downloads, for a mirror. Default https://github.com/softberries/tayga/releases/download; the bundle is fetched from <base>/v<version>/. |
Running it again is safe. It updates the settings it manages in .env (TAYGA_VERSION, the ports, the bind address, the project name, and TAYGA_PUBLIC_URL while it is still a http://localhost: URL) and runs docker compose up -d again; your data stays. It replaces compose.yaml, but never your edited notifier.toml or otel-collector.yaml: the new copies go next to them as *.new. It creates the directory readable by you only, because .env and notifier.toml hold secrets, and copies itself to <dir>/install.sh, so later you can run:
sh ~/tayga/install.sh --uninstallInstall by hand
Section titled “Install by hand”Without the installer, unpack the bundle (or use deploy/standalone in a checkout) and:
-
Create
.envfrom the example and setTAYGA_VERSIONto a release:Terminal window cp .env.example .env -
Start the stack:
Terminal window docker compose up -d -
Wait until
tayga-apireads(healthy):Terminal window docker compose ps
To run an image you built yourself, from a checkout:
docker build -f docker/Dockerfile -t tayga:local .sh scripts/install.sh --localOpen the app at http://localhost:8090. It is empty until telemetry arrives.
Configuration (.env)
Section titled “Configuration (.env)”Everything is set in .env next to compose.yaml. After a change run docker compose up -d (or the installer again), which recreates the containers whose settings changed.
| Variable | Default | Meaning |
|---|---|---|
COMPOSE_PROJECT_NAME |
tayga |
Compose project name |
TAYGA_VERSION |
latest |
Image tag of ghcr.io/softberries/tayga. Pin a release. |
TAYGA_IMAGE |
unset | A whole image reference that replaces the GHCR image, for example tayga:local |
TAYGA_BIND |
127.0.0.1 |
Address the published ports bind to |
TAYGA_HTTP_PORT |
8090 |
Host port of the web app and API |
TAYGA_OTLP_GRPC_PORT, TAYGA_OTLP_HTTP_PORT |
4317, 4318 |
Host ports of the OTLP receivers |
TAYGA_PUBLIC_URL |
http://localhost:8090 |
Base of the links in alert notifications: where people open the app |
LOGMINER_REPLICAS |
1 |
Logminer replicas. tayga.logs has 12 partitions; replicas beyond 12 idle. See Scaling logminer replicas. |
LOGMINER_FINGERPRINTER |
scalar |
Fingerprint cache in front of Drain: scalar, parallel or off. See Performance tuning. |
REDPANDA_MEMORY |
1G |
Redpanda’s memory (Seastar --memory) |
RUST_LOG |
info |
Log filter of the Tayga services |
TAYGA_AUTH_ENABLED, TAYGA_AUTH_USERNAME, TAYGA_AUTH_PASSWORD_HASH, TAYGA_AUTH_SESSION_KEY, TAYGA_AUTH_SECURE_COOKIE |
off | Login; see Authentication |
Any other setting
Section titled “Any other setting”Every Tayga setting has a TAYGA__SECTION__KEY environment variable (Configuration reference). Add the ones you need in a compose.override.yaml next to compose.yaml; Compose loads it automatically, and the installer never touches it:
services: tayga-assembler: environment: TAYGA__ASSEMBLER__GAP_MS: "15000" tayga-api: environment: TAYGA__QUERY_TIMEOUT_SECS: "30"Authentication
Section titled “Authentication”Off by default: anyone who reaches port 8090 can read every trace and log. One account protects the app and every data route once it is on; details are in Authentication.
-
Make a password hash. The Tayga image ships
tayga-devtools, which asks for the password twice without echo (or reads the first line of piped input) and prints an Argon2id hash:Terminal window docker compose exec tayga-api tayga-devtools hash-passwordWithout a running stack, use the image directly; in a script, pipe the password in:
Terminal window docker run --rm -it ghcr.io/softberries/tayga:0.1.0 tayga-devtools hash-passwordprintf '%s' 'my password' | docker compose exec -T tayga-api tayga-devtools hash-passwordprintf '%s' 'my password' | docker run --rm -i ghcr.io/softberries/tayga:0.1.0 tayga-devtools hash-passwordThe output starts
$argon2id$v=19$m=19456,t=2,p=1$. Any Argon2id PHC string works. -
Make a session key, so that a restart does not sign everyone out:
Terminal window openssl rand -base64 32 -
Put both in
.env. Keep the single quotes around the hash: it contains$..env TAYGA_AUTH_ENABLED=trueTAYGA_AUTH_USERNAME=adminTAYGA_AUTH_PASSWORD_HASH='$argon2id$v=19$m=19456,t=2,p=1$...'TAYGA_AUTH_SESSION_KEY=<output of openssl rand -base64 32> -
Recreate the API:
Terminal window docker compose up -d tayga-apiThe app now shows a sign-in page, and the API answers 401 without a session. Scripts can send HTTP Basic credentials:
curl -u admin:'my password' http://localhost:8090/api/v1/story-groups.
Behind an HTTPS reverse proxy, also set TAYGA_AUTH_SECURE_COOKIE=true.
Exposing the ports
Section titled “Exposing the ports”By default every published port binds to 127.0.0.1, so only this machine reaches Tayga. To reach it from other machines, set TAYGA_BIND=0.0.0.0 (or one interface’s address) in .env and run docker compose up -d, or install with --bind 0.0.0.0. Before you do:
- Turn on authentication, or put an authenticating reverse proxy in front of port 8090.
- The OTLP ports accept data from anyone who reaches them, with no authentication and no TLS. Prefer a Collector on the trusted side that forwards to Tayga, or a firewall that admits only your senders.
- Tayga serves plain HTTP. For HTTPS, terminate TLS in a reverse proxy and set
TAYGA_AUTH_SECURE_COOKIE=true. - Set
TAYGA_PUBLIC_URLto the address people use, so the links in alert notifications work.
ClickHouse and Redpanda are never published. ClickHouse’s default user has no password (Tayga does not support ClickHouse credentials yet); only containers on the Compose network reach it.
Sending telemetry
Section titled “Sending telemetry”Tayga reads OTLP traces and logs; it ignores metrics.
- SDKs on the same host:
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318(HTTP) orhttp://localhost:4317(gRPC). - A container on the same Docker host: join the network
tayga_defaultand send totayga-ingest:4317orhttp://tayga-ingest:4318. - Your own OpenTelemetry Collector: add the Tayga exporter to its traces and logs pipelines. Connect your Collector has the snippets.
The bundled Collector config or your own
Section titled “The bundled Collector config or your own”The bundle includes otel-collector.yaml, a complete Collector config that receives OTLP and forwards traces and logs to Tayga. It is not started by compose.yaml; use it in one of two ways:
If you have no Collector yet, run the sample next to the stack. It joins the stack’s network and receives on 127.0.0.1:5317 (gRPC) and 5318 (HTTP), so your services send to it instead of to Tayga directly:
cd ~/taygadocker run -d --name tayga-otelcol --network tayga_default \ -p 127.0.0.1:5317:4317 -p 127.0.0.1:5318:4318 \ -v "$PWD/otel-collector.yaml:/etc/otelcol-contrib/config.yaml:ro" \ otel/opentelemetry-collector-contrib:0.162.0It batches, compresses, queues in memory and retries for up to 5 minutes, so it rides out a short Tayga restart.
Copy the otlp_grpc/tayga exporter from otel-collector.yaml into your Collector’s config and append it to the exporters of your traces and logs pipelines, next to the ones you have. Set endpoint to the address your Collector reaches Tayga at: localhost:4317 on the Docker host, or tayga-ingest:4317 from a container on tayga_default.
A quick test
Section titled “A quick test”docker run --rm --network tayga_default ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen:latest \ traces --otlp-endpoint tayga-ingest:4317 --otlp-insecure --traces 20 --child-spans 3 --status-code Error --service checkoutError stories appear on the Stories page a few seconds after a trace ends (the assembler closes a trace 10 s after its last span). The Quickstart has a logs example too.
Alert delivery
Section titled “Alert delivery”Log alerts show in the app without any setup. To also send them to a webhook or Slack, add targets to notifier.toml in the install directory and restart the notifier:
[[notifier.targets]]name = "ops-slack"kind = "slack" # or "webhook"url = "https://hooks.slack.com/services/..."docker compose restart tayga-notifierA Slack incoming-webhook URL is a credential. Keep the install directory private (chmod 700, as the installer creates it) rather than the file: the notifier runs as uid 10001 and must be able to read notifier.toml, so a chmod 600 on the file stops it on Linux. The formats and the retry rules are in Alerting.
Day-to-day commands
Section titled “Day-to-day commands”Run these in the install directory:
docker compose ps # status; tayga-api and tayga-ingest have healthchecksdocker compose logs -f tayga-api # logs of one servicedocker compose restart tayga-notifier # after editing notifier.tomldocker compose exec clickhouse clickhouse-client # SQL on the tayga databaseRe-mining log templates after a Drain or masking change runs tayga-devtools in the logminer container; see Re-mining templates.
Retention: raw spans and logs are kept 3 days, trace summaries 2 days, stories, service edges and alerts 7 days (ClickHouse TTLs). Redpanda topics keep 24 hours.
