Skip to main content
Docker Compose deployments default to basic email / password authentication. Production deployments should use OIDC or SAML SSO. See Security for additional production hardening recommendations.

Prerequisites

Core secrets

The env.sh script (next step) generates these automatically. If you need to generate them manually:

Download configuration files

# 1. Download the env.sh installation script
curl -o env.sh https://raw.githubusercontent.com/TracecatHQ/tracecat/1.0.0-beta.39/env.sh

# 2. Download the .env.example template file (env.sh needs this to generate your .env file)
curl -o .env.example https://raw.githubusercontent.com/TracecatHQ/tracecat/1.0.0-beta.39/.env.example

# 3. Make the env.sh script executable and run it
chmod +x env.sh && ./env.sh
After running env.sh, you’ll be prompted to input the following:
  • Set PUBLIC_APP_URL. Defaults to localhost.
  • Require PostgreSQL SSL mode? Defaults to n.
  • Required field: Enter email address for the first user (superadmin).

Download Caddyfile

Tracecat uses Caddy as a reverse proxy. You’ll need to download the following Caddyfile to configure this service.
curl -o Caddyfile https://raw.githubusercontent.com/TracecatHQ/tracecat/1.0.0-beta.39/Caddyfile

Download Docker Compose file

curl -o docker-compose.yml https://raw.githubusercontent.com/TracecatHQ/tracecat/1.0.0-beta.39/docker-compose.yml

Start Tracecat

Run the command below to start Tracecat and all related services. Make sure your docker-compose.yml and generated .env files are in the same directory.
docker compose up

Access Tracecat

Once deployed, access your instance at:
  • UI: http://localhost:${PUBLIC_APP_PORT}
  • API docs: http://localhost:${PUBLIC_APP_PORT}/api/docs
  • MCP: http://localhost:${PUBLIC_APP_PORT}/mcp

Updating Tracecat

Be careful when updating Tracecat. Do not accidentally overwrite or lose your existing TRACECAT__SERVICE_KEY, TRACECAT__SIGNING_SECRET, TRACECAT__DB_ENCRYPTION_KEY, and USER_AUTH_SECRET secrets. Losing these secrets will break your credentials and webhooks.
# 1. Download the latest env migration script and env template
curl -o env-migration.sh https://raw.githubusercontent.com/TracecatHQ/tracecat/<version>/env-migration.sh
curl -o .env.example https://raw.githubusercontent.com/TracecatHQ/tracecat/<version>/.env.example

# 2. Make the migration script executable and update your existing .env
chmod +x env-migration.sh && ./env-migration.sh

# 3. Download the latest Docker Compose file
curl -o docker-compose.yml https://raw.githubusercontent.com/TracecatHQ/tracecat/<version>/docker-compose.yml

# 4. Download the latest Caddyfile
curl -o Caddyfile https://raw.githubusercontent.com/TracecatHQ/tracecat/<version>/Caddyfile

# 5. Restart Tracecat with the updated configuration
docker compose up -d
The migration script creates a backup of your existing .env before rewriting it. After the stack starts, verify that your containers are healthy and that you can sign in successfully.

Scaling

Docker Compose runs all services on a single host. These are recommended minimums for different workload sizes.
ResourceSmallStandardProduction
CPU8 cores16 cores32+ cores
RAM16 GB32 GB64+ GB
Storage20 GB SSD50 GB SSD100+ GB SSD
Docker26.0.0+26.0.0+26.0.0+
Workflow starts/sec~5~15~40
Concurrent seats1-1010-5050+
Concurrent agents/sec1-25-1010+
  • Small: Development, testing, small teams (1-10 users)
  • Standard: Mid-size teams (10-50 users), moderate workflow execution
  • Production: Large teams (50+ users), high throughput
Memory is typically the constraining factor. Workflow throughput is lower than dedicated Kubernetes deployments where services have guaranteed resources and can scale independently. For production workloads that exceed single-host capacity, consider converting to Docker Swarm or deploying on Kubernetes.

Convert to Docker Swarm

Docker Swarm lets you scale individual services with resource limits and replicas across one or more nodes.

Service resource recommendations

ServiceCPU (cores)MemoryReplicas
caddy0.25256 Mi1
api24 Gi2
worker22 Gi4
executor48 Gi4
agent-worker22 Gi2
agent-executor416 Gi2
ui0.51 Gi2
mcp11 Gi1
postgres_db24 Gi1
temporal24 Gi1
temporal_postgres_db12 Gi1
redis0.51 Gi1
minio0.51 Gi1
Total~22~46 Gi23
Stateful services (postgres_db, temporal_postgres_db, minio, redis) must remain at 1 replica. Scaling these requires external managed services (e.g., RDS, ElastiCache) or specialized clustering.

Deploy with Docker Swarm

  1. Initialize Swarm:
docker swarm init
  1. Add deploy configuration to each service in your docker-compose.yml. For example, for the api service:
services:
  api:
    # ... existing configuration ...
    deploy:
      replicas: 2
      resources:
        limits:
          cpus: "2"
          memory: 4G
        reservations:
          cpus: "2"
          memory: 4G
  1. Deploy the stack:
docker stack deploy -c docker-compose.yml tracecat
  1. Verify services are running:
docker stack services tracecat

FAQ

The stack runs 15 containers grouped into application and infrastructure services.Application services:
  • caddy — Reverse proxy that routes traffic to the UI, API, and MCP
  • api — FastAPI backend (port 8000)
  • ui — Next.js frontend (port 3000)
  • worker — Workflow orchestrator (Temporal worker)
  • executor — Action executor with optional sandbox isolation
  • agent-worker — AI agent orchestrator
  • agent-executor — AI agent executor with LLM gateway support
  • mcp — Model Context Protocol server (port 8099)
Infrastructure services:
  • postgres_db — PostgreSQL 16 (application database)
  • temporal — Temporal workflow engine (auto-setup)
  • temporal_postgres_db — PostgreSQL 13 (Temporal database)
  • temporal_ui — Temporal web UI (not exposed by default)
  • minio — S3-compatible object storage
  • redis — Cache and task queue
  • migrations — One-shot database migration runner (exits after completion)
Yes. Tracecat uses Dex as a built-in OIDC provider for MCP. Dex is shipped with the Tracecat Docker Compose stack.Seek assistance in our #help-chat channel if you encounter any issues.
Yes but don’t forget to set PUBLIC_APP_URL to 127.0.0.1 instead of localhost in your .env file.
Yes but you’ll need to set PUBLIC_APP_URL to the WSL IP address instead of localhost. Run ip addr to find your WSL IP address (usually 172.x.x.x).
This suggests that the Tracecat UI is healthy but is unable to communicate with the Tracecat API.
  • Check that the api service is healthy
  • Check that this is not a CORS issue (see next FAQ)
  • Check that you changed PUBLIC_APP_URL and PUBLIC_APP_PORT to the correct address
  • Check the Chrome developer console for any errors
You must configure PUBLIC_APP_URL and PUBLIC_API_URL to the same domain that your browser is accessing the Tracecat UI from. Tracecat strictly enforces CORS to prevent XSS attacks.This error occurs when your browser cannot connect to Tracecat API via PUBLIC_APP_URL. Please check the following:
  • Do not set PUBLIC_APP_URL to 0.0.0.0. Browsers cannot connect to this address. Use localhost, 127.0.0.1, or your machine’s actual IP address instead.
  • WSL users: Do not use 127.0.0.1. Run ip addr to find your WSL IP address (usually 172.x.x.x) and use that instead.
  • If your frontend is running on a different machine than the API, set NEXT_PUBLIC_API_URL to an address your browser can reach.
  • Run docker compose ps to verify all services are running.
  • Check the temporal service is healthy. Worker connectivity issues can sometimes affect login.
  • View container logs: docker compose logs api and docker compose logs temporal.
  • Check firewall and port forwarding if using a reverse proxy.
For example, if you’ve deployed Tracecat into a VM and exposed it to your browser as https://my-tracecat-instance.com, you must set:
  • PUBLIC_APP_URL to https://my-tracecat-instance.com
  • PUBLIC_API_URL to https://my-tracecat-instance.com/api
Set both values to the exact browser-reachable URLs for your deployment, including the scheme:
  • Local example:
    • PUBLIC_APP_URL=http://localhost:8000
    • PUBLIC_API_URL=http://localhost:8000/api
  • Reverse proxy or public domain example:
    • PUBLIC_APP_URL=https://tracecat.example.com
    • PUBLIC_API_URL=https://tracecat.example.com/api
Use full URLs once. Do not prepend http:// or https:// twice, and do not use addresses that only work inside Docker such as 0.0.0.0 or internal container hostnames.If sign-in still fails:
  • Verify that the domain in your browser exactly matches PUBLIC_APP_URL.
  • Verify that PUBLIC_API_URL is the same origin plus /api.
  • Run docker compose ps and check that api, worker, and temporal are healthy.
  • Review docker compose logs api for startup, auth, or CORS errors.
Tracecat ships with Caddy as a reverse proxy. Caddy automatically provisions and renews TLS certificates from Let’s Encrypt when configured with a domain name.
1

Update environment variables

In your .env file, set BASE_DOMAIN to your domain and update the public URLs to use HTTPS:
BASE_DOMAIN=tracecat.example.com
PUBLIC_APP_URL=https://tracecat.example.com
PUBLIC_API_URL=https://tracecat.example.com/api
2

Expose ports 80 and 443

Update the caddy service ports in your docker-compose.yml:
services:
  caddy:
    ports:
      - "80:80"
      - "443:443"
Port 80 must remain open for the ACME HTTP-01 challenge. Port 443 serves HTTPS traffic.
3

Restart the stack

docker compose up -d
Caddy will automatically obtain and renew certificates on startup.