Docker Compose
Runs Traceway, ClickHouse, and PostgreSQL as separate services using the Minimal Container image.
Quick Start
No build required — use the pre-built image from GitHub Container Registry with this docker-compose.yml:
services:
traceway:
image: ghcr.io/tracewayapp/traceway:minimal
ports:
- "80:80"
environment:
CLICKHOUSE_SERVER: "clickhouse:9000"
CLICKHOUSE_DATABASE: "traceway"
CLICKHOUSE_USERNAME: "default"
CLICKHOUSE_PASSWORD: "clickhouse"
CLICKHOUSE_TLS: "false"
POSTGRES_HOST: "postgres"
POSTGRES_PORT: "5432"
POSTGRES_DATABASE: "traceway"
POSTGRES_USERNAME: "traceway"
POSTGRES_PASSWORD: "traceway"
POSTGRES_SSLMODE: "disable"
JWT_SECRET: "change-this-to-a-secure-secret-at-least-32-chars"
volumes:
- traceway-storage:/app/storage
depends_on:
clickhouse:
condition: service_healthy
postgres:
condition: service_healthy
restart: unless-stopped
clickhouse:
image: clickhouse/clickhouse-server:24.8-alpine
environment:
CLICKHOUSE_DB: traceway
CLICKHOUSE_PASSWORD: clickhouse
volumes:
- clickhouse-data:/var/lib/clickhouse
healthcheck:
test: ["CMD", "clickhouse-client", "--password", "clickhouse", "--query", "SELECT 1"]
interval: 5s
timeout: 3s
start_period: 10s
retries: 10
restart: unless-stopped
postgres:
image: postgres:17
environment:
POSTGRES_USER: traceway
POSTGRES_PASSWORD: traceway
POSTGRES_DB: traceway
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U traceway"]
interval: 5s
timeout: 3s
start_period: 10s
retries: 10
restart: unless-stopped
volumes:
clickhouse-data:
postgres-data:
traceway-storage:docker compose up -dAfter starting, open http://localhost/register to create your first account.
The traceway-storage volume holds blob storage: uploaded source maps, session recordings, and AI traces. Without it those files are lost when the container is recreated. To use S3 instead of a volume, see Blob Storage.
The docker-compose.yml in the repository root builds from source instead. Use that if you are actively developing Traceway or need to run a modified build (docker compose up --build).
Configuration
Edit the environment variables in your compose file as needed:
| Variable | Default | Description |
|---|---|---|
CLICKHOUSE_SERVER | clickhouse:9000 | ClickHouse host:port |
CLICKHOUSE_DATABASE | traceway | ClickHouse database name |
CLICKHOUSE_USERNAME | default | ClickHouse username |
CLICKHOUSE_PASSWORD | clickhouse | ClickHouse password |
CLICKHOUSE_TLS | false | Enable TLS for ClickHouse |
POSTGRES_HOST | postgres | PostgreSQL host |
POSTGRES_PORT | 5432 | PostgreSQL port |
POSTGRES_DATABASE | traceway | PostgreSQL database name |
POSTGRES_USERNAME | traceway | PostgreSQL username |
POSTGRES_PASSWORD | traceway | PostgreSQL password |
POSTGRES_SSLMODE | disable | PostgreSQL SSL mode |
JWT_SECRET | change-this-to-a-secure-secret-at-least-32-chars | Signs all authentication tokens (dashboard sessions and CLI/MCP device logins). Replace the placeholder with a strong, unique secret of at least 32 chars (openssl rand -hex 32) and keep it stable. See CLI Authentication. |
APP_BASE_URL | (none) | Public URL of your Traceway instance (e.g. https://traceway.example.com). Used for SDK setup instructions, email links, OAuth callback URLs, and the CLI/MCP OAuth issuer plus device-login verification URL. If unset, the device-auth and /.well-known endpoints derive it per-request from the Host / X-Forwarded-* headers; set it explicitly behind a proxy that rewrites Host. See CLI Authentication. |
STORAGE_TYPE | local | Blob storage backend for source maps, session recordings, and AI traces: local or s3. See Blob Storage for the S3 variables. |
STORAGE_PATH | ./storage | Folder for local blob storage, /app/storage in the minimal image. Mount a volume there. Ignored when STORAGE_TYPE=s3. |
SESSION_RECORDING_RETENTION_DAYS | 30 | Days to keep session recording files on disk under STORAGE_PATH/recordings/. A worker deletes older files hourly and on startup. No effect when STORAGE_TYPE=s3. Set to 0 to disable. |
ClickHouse table TTLs (
metric_points,log_records, etc.) are managed at the schema level; this stack does not run the SQLite retention worker.
SSO (optional)
Adds Continue with Google / Continue with GitHub buttons to the login and register pages. See the SSO guide for the full provider setup walkthrough.
When configuring providers, set the callback URL on the provider side to <APP_BASE_URL>/api/auth/callback/{google|github}.
| Variable | Default | Description |
|---|---|---|
GOOGLE_CLIENT_ID | (unset) | Google OAuth client ID. Setting both Google variables enables the Google button. |
GOOGLE_CLIENT_SECRET | (unset) | Google OAuth client secret. |
GITHUB_CLIENT_ID | (unset) | GitHub OAuth App client ID. Setting both GitHub variables enables the GitHub button. |
GITHUB_CLIENT_SECRET | (unset) | GitHub OAuth App client secret. |
OAUTH_SESSION_SECRET | (falls back to JWT_SECRET) | Cookie signing secret for the OAuth round-trip. Override to rotate independently of JWT_SECRET. |
Access Points
| URL | Description |
|---|---|
http://localhost/ | Frontend dashboard |
http://localhost/api/* | Backend API |
http://localhost/health | Health check |
Useful Commands
# View logs for all services
docker compose logs -f
# View logs for a specific service
docker compose logs -f traceway
# Stop all services
docker compose down
# Stop and remove all data
docker compose down -v