services: caddy: image: caddy:2.10.2-alpine restart: unless-stopped ports: - ${PUBLIC_APP_PORT}:${PUBLIC_APP_PORT} environment: - BASE_DOMAIN=${BASE_DOMAIN} - ADDRESS=${ADDRESS} - TRACECAT__TRUSTED_PROXY_CIDRS=${TRACECAT__TRUSTED_PROXY_CIDRS:-127.0.0.1/32} volumes: - ./Caddyfile:/etc/caddy/Caddyfile api: build: context: . dockerfile: Dockerfile target: development restart: unless-stopped ports: - ${API_PORT:-8000}:8000 environment: # App TRACECAT__AUDIT_TRUSTED_PROXY_CIDRS: ${TRACECAT__AUDIT_TRUSTED_PROXY_CIDRS:-} TRACECAT__PLATFORM_ADMIN_IP_ALLOWLIST_BYPASS: ${TRACECAT__PLATFORM_ADMIN_IP_ALLOWLIST_BYPASS:-false} TRACECAT__PLATFORM_ADMIN_MFA_BYPASS: ${TRACECAT__PLATFORM_ADMIN_MFA_BYPASS:-false} LOG_LEVEL: ${LOG_LEVEL} TRACECAT__LOG_FORMAT: ${TRACECAT__LOG_FORMAT:-console} TRACECAT__PLATFORM_OTEL_ENABLED: ${TRACECAT__PLATFORM_OTEL_ENABLED:-false} OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318} OTEL_TRACES_SAMPLER: ${OTEL_TRACES_SAMPLER:-parentbased_traceidratio} OTEL_TRACES_SAMPLER_ARG: ${OTEL_TRACES_SAMPLER_ARG:-1.0} OTEL_EXPORTER_OTLP_HEADERS: ${OTEL_EXPORTER_OTLP_HEADERS:-} TRACECAT__ALLOW_ORIGINS: ${TRACECAT__ALLOW_ORIGINS} TRACECAT__API_ROOT_PATH: ${TRACECAT__API_ROOT_PATH} TRACECAT__API_URL: ${TRACECAT__API_URL} TRACECAT__APP_ENV: ${TRACECAT__APP_ENV} TRACECAT__AWS_ASSUME_ROLE_ACCOUNT_ID: ${TRACECAT__AWS_ASSUME_ROLE_ACCOUNT_ID:-} TRACECAT__AWS_ASSUME_ROLE_PRINCIPAL_ARN: ${TRACECAT__AWS_ASSUME_ROLE_PRINCIPAL_ARN:-} TRACECAT__AUTH_ALLOWED_DOMAINS: ${TRACECAT__AUTH_ALLOWED_DOMAINS} TRACECAT__AUTH_MIN_PASSWORD_LENGTH: ${TRACECAT__AUTH_MIN_PASSWORD_LENGTH} TRACECAT__AUTH_TYPES: ${TRACECAT__AUTH_TYPES} TRACECAT__AUTH_SUPERADMIN_EMAIL: ${TRACECAT__AUTH_SUPERADMIN_EMAIL} TRACECAT__DEV_COOKIE_NAME: ${TRACECAT__DEV_COOKIE_NAME:-} TRACECAT__DB_ENCRYPTION_KEY: ${TRACECAT__DB_ENCRYPTION_KEY} # Sensitive TRACECAT__DB_SSLMODE: ${TRACECAT__DB_SSLMODE} TRACECAT__DB_URI: ${TRACECAT__DB_URI} # Sensitive TRACECAT__PUBLIC_API_URL: ${TRACECAT__PUBLIC_API_URL} TRACECAT__PUBLIC_APP_URL: ${TRACECAT__PUBLIC_APP_URL} TRACECAT__SMTP_HOST: ${TRACECAT__SMTP_HOST:-} TRACECAT__SMTP_PORT: ${TRACECAT__SMTP_PORT:-587} TRACECAT__SMTP_USER: ${TRACECAT__SMTP_USER:-} TRACECAT__SMTP_PASSWORD: ${TRACECAT__SMTP_PASSWORD:-} # Sensitive TRACECAT__EMAIL_FROM: ${TRACECAT__EMAIL_FROM:-} TRACECAT__SERVICE_KEY: ${TRACECAT__SERVICE_KEY} # Sensitive TRACECAT__SERVICE_NAME: api SENTRY_DSN: ${SENTRY_DSN:-} TRACECAT__AGENT_SANDBOX_TIMEOUT: ${TRACECAT__AGENT_SANDBOX_TIMEOUT:-10800} TRACECAT__DB_POOL_TIMEOUT: ${TRACECAT__DB_POOL_TIMEOUT:-30} TRACECAT__DB_AUTH_POOL_SIZE: ${TRACECAT__DB_AUTH_POOL_SIZE:-5} TRACECAT__DB_AUTH_MAX_OVERFLOW: ${TRACECAT__DB_AUTH_MAX_OVERFLOW:-5} TRACECAT__SIGNING_SECRET: ${TRACECAT__SIGNING_SECRET} # Sensitive OAUTH_CLIENT_ID: ${OAUTH_CLIENT_ID} OAUTH_CLIENT_SECRET: ${OAUTH_CLIENT_SECRET} OIDC_ISSUER: ${OIDC_ISSUER} OIDC_CLIENT_ID: ${OIDC_CLIENT_ID} OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET} OIDC_SCOPES: ${OIDC_SCOPES} USER_AUTH_SECRET: ${USER_AUTH_SECRET} TRACECAT__FEATURE_FLAGS: ${TRACECAT__FEATURE_FLAGS} TRACECAT__EE_MULTI_TENANT: ${TRACECAT__EE_MULTI_TENANT:-false} TRACECAT__LITELLM_BASE_URL: ${TRACECAT__LITELLM_BASE_URL:-http://litellm:4000} TRACECAT__OUTBOUND_ALLOWED_PRIVATE_CIDRS: ${TRACECAT__OUTBOUND_ALLOWED_PRIVATE_CIDRS:-} TRACECAT__CONTEXT_COMPRESSION_ENABLED: ${TRACECAT__CONTEXT_COMPRESSION_ENABLED:-false} TRACECAT__CONTEXT_COMPRESSION_THRESHOLD_KB: ${TRACECAT__CONTEXT_COMPRESSION_THRESHOLD_KB:-16} TRACECAT__RESULT_EXTERNALIZATION_ENABLED: ${TRACECAT__RESULT_EXTERNALIZATION_ENABLED:-true} TRACECAT__COLLECTION_MANIFESTS_ENABLED: ${TRACECAT__COLLECTION_MANIFESTS_ENABLED:-true} TRACECAT__RESULT_EXTERNALIZATION_THRESHOLD_BYTES: ${TRACECAT__RESULT_EXTERNALIZATION_THRESHOLD_BYTES} TRACECAT__UNSAFE_DISABLE_SECRET_ERROR_WITHHOLDING: ${TRACECAT__UNSAFE_DISABLE_SECRET_ERROR_WITHHOLDING:-false} # SAML SSO SAML_IDP_METADATA_URL: ${SAML_IDP_METADATA_URL} # Temporal TEMPORAL__CLUSTER_URL: ${TEMPORAL__CLUSTER_URL} TRACECAT__BACKGROUND_QUEUE: ${TRACECAT__BACKGROUND_QUEUE:-shared-background-queue} TEMPORAL__CLUSTER_QUEUE: ${TEMPORAL__CLUSTER_QUEUE} TEMPORAL__CLUSTER_NAMESPACE: ${TEMPORAL__CLUSTER_NAMESPACE} TEMPORAL__API_KEY: ${TEMPORAL__API_KEY} TEMPORAL__PAYLOAD_ENCRYPTION_ENABLED: ${TEMPORAL__PAYLOAD_ENCRYPTION_ENABLED:-false} TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING: ${TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING:-} TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING_ARN: ${TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING_ARN:-} TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_TTL_SECONDS: ${TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_TTL_SECONDS:-3600} TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_MAX_ITEMS: ${TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_MAX_ITEMS:-128} # Blob Storage TRACECAT__BLOB_STORAGE_ENDPOINT: ${TRACECAT__BLOB_STORAGE_ENDPOINT:-http://minio:9000} TRACECAT__BLOB_STORAGE_SSL_VERIFY: ${TRACECAT__BLOB_STORAGE_SSL_VERIFY:-true} TRACECAT__BLOB_STORAGE_BUCKET_SKILLS: ${TRACECAT__BLOB_STORAGE_BUCKET_SKILLS:-tracecat-skills} TRACECAT__BLOB_STORAGE_PRESIGNED_URL_ENDPOINT: ${TRACECAT__BLOB_STORAGE_PRESIGNED_URL_ENDPOINT:-${TRACECAT__PUBLIC_APP_URL}/s3} TRACECAT__WORKFLOW_ARTIFACT_RETENTION_DAYS: ${TRACECAT__WORKFLOW_ARTIFACT_RETENTION_DAYS:-30} MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} # Local registry TRACECAT__LOCAL_REPOSITORY_PATH: ${TRACECAT__LOCAL_REPOSITORY_PATH} TRACECAT__LOCAL_REPOSITORY_ENABLED: ${TRACECAT__LOCAL_REPOSITORY_ENABLED:-false} # Redis REDIS_URL: ${REDIS_URL} volumes: - ./tracecat:/app/tracecat - ./packages:/app/packages - ./alembic:/app/alembic - ${TRACECAT__LOCAL_REPOSITORY_PATH}:/app/local_registry depends_on: migrations: condition: service_completed_successfully temporal: condition: service_healthy minio: condition: service_healthy redis: condition: service_healthy healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:$${PORT:-8000}/health"] interval: 5s timeout: 5s retries: 30 start_period: 10s worker: build: context: . dockerfile: Dockerfile target: development restart: unless-stopped environment: LOG_LEVEL: ${LOG_LEVEL} TRACECAT__LOG_FORMAT: ${TRACECAT__LOG_FORMAT:-console} TRACECAT__PLATFORM_OTEL_ENABLED: ${TRACECAT__PLATFORM_OTEL_ENABLED:-false} OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318} OTEL_TRACES_SAMPLER: ${OTEL_TRACES_SAMPLER:-parentbased_traceidratio} OTEL_TRACES_SAMPLER_ARG: ${OTEL_TRACES_SAMPLER_ARG:-1.0} OTEL_EXPORTER_OTLP_HEADERS: ${OTEL_EXPORTER_OTLP_HEADERS:-} TRACECAT__API_ROOT_PATH: ${TRACECAT__API_ROOT_PATH} TRACECAT__API_URL: ${TRACECAT__API_URL} TRACECAT__APP_ENV: ${TRACECAT__APP_ENV} TRACECAT__AWS_ASSUME_ROLE_ACCOUNT_ID: ${TRACECAT__AWS_ASSUME_ROLE_ACCOUNT_ID:-} TRACECAT__AWS_ASSUME_ROLE_PRINCIPAL_ARN: ${TRACECAT__AWS_ASSUME_ROLE_PRINCIPAL_ARN:-} TRACECAT__DB_ENCRYPTION_KEY: ${TRACECAT__DB_ENCRYPTION_KEY} # Sensitive TRACECAT__DB_SSLMODE: ${TRACECAT__DB_SSLMODE} TRACECAT__DB_URI: ${TRACECAT__DB_URI} # Sensitive TRACECAT__PUBLIC_API_URL: ${TRACECAT__PUBLIC_API_URL} TRACECAT__PUBLIC_APP_URL: ${TRACECAT__PUBLIC_APP_URL} TRACECAT__SERVICE_KEY: ${TRACECAT__SERVICE_KEY} # Sensitive TRACECAT__SERVICE_NAME: worker TRACECAT__AGENT_SANDBOX_TIMEOUT: ${TRACECAT__AGENT_SANDBOX_TIMEOUT:-10800} TRACECAT__DB_POOL_TIMEOUT: ${TRACECAT__DB_POOL_TIMEOUT:-30} TRACECAT__DB_AUTH_POOL_SIZE: ${TRACECAT__DB_AUTH_POOL_SIZE:-5} TRACECAT__DB_AUTH_MAX_OVERFLOW: ${TRACECAT__DB_AUTH_MAX_OVERFLOW:-5} TRACECAT__SIGNING_SECRET: ${TRACECAT__SIGNING_SECRET} # Sensitive TRACECAT__FEATURE_FLAGS: ${TRACECAT__FEATURE_FLAGS} TRACECAT__EE_MULTI_TENANT: ${TRACECAT__EE_MULTI_TENANT:-false} TRACECAT__CONTEXT_COMPRESSION_ENABLED: ${TRACECAT__CONTEXT_COMPRESSION_ENABLED:-false} TRACECAT__CONTEXT_COMPRESSION_THRESHOLD_KB: ${TRACECAT__CONTEXT_COMPRESSION_THRESHOLD_KB:-16} TRACECAT__RESULT_EXTERNALIZATION_ENABLED: ${TRACECAT__RESULT_EXTERNALIZATION_ENABLED:-true} TRACECAT__COLLECTION_MANIFESTS_ENABLED: ${TRACECAT__COLLECTION_MANIFESTS_ENABLED:-true} TRACECAT__RESULT_EXTERNALIZATION_THRESHOLD_BYTES: ${TRACECAT__RESULT_EXTERNALIZATION_THRESHOLD_BYTES} TRACECAT__UNSAFE_DISABLE_SECRET_ERROR_WITHHOLDING: ${TRACECAT__UNSAFE_DISABLE_SECRET_ERROR_WITHHOLDING:-false} # Temporal TEMPORAL__CLUSTER_URL: ${TEMPORAL__CLUSTER_URL} TRACECAT__BACKGROUND_QUEUE: ${TRACECAT__BACKGROUND_QUEUE:-shared-background-queue} TEMPORAL__CLUSTER_QUEUE: ${TEMPORAL__CLUSTER_QUEUE} TEMPORAL__CLUSTER_NAMESPACE: ${TEMPORAL__CLUSTER_NAMESPACE} TEMPORAL__API_KEY: ${TEMPORAL__API_KEY} TEMPORAL__PAYLOAD_ENCRYPTION_ENABLED: ${TEMPORAL__PAYLOAD_ENCRYPTION_ENABLED:-false} TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING: ${TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING:-} TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING_ARN: ${TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING_ARN:-} TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_TTL_SECONDS: ${TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_TTL_SECONDS:-3600} TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_MAX_ITEMS: ${TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_MAX_ITEMS:-128} # Worker concurrency tuning TEMPORAL__THREADPOOL_MAX_WORKERS: ${TEMPORAL__THREADPOOL_MAX_WORKERS:-100} TEMPORAL__MAX_CONCURRENT_ACTIVITIES: ${TEMPORAL__MAX_CONCURRENT_ACTIVITIES:-100} TEMPORAL__MAX_CONCURRENT_WORKFLOW_TASKS: ${TEMPORAL__MAX_CONCURRENT_WORKFLOW_TASKS:-100} # Local registry TRACECAT__LOCAL_REPOSITORY_PATH: ${TRACECAT__LOCAL_REPOSITORY_PATH} TRACECAT__LOCAL_REPOSITORY_ENABLED: ${TRACECAT__LOCAL_REPOSITORY_ENABLED:-false} TRACECAT__EXECUTOR_CLIENT_TIMEOUT: ${TRACECAT__EXECUTOR_CLIENT_TIMEOUT:-300} # Sentry SENTRY_DSN: ${SENTRY_DSN:-} # Redis REDIS_URL: ${REDIS_URL} # Blob storage (for S3) TRACECAT__BLOB_STORAGE_ENDPOINT: ${TRACECAT__BLOB_STORAGE_ENDPOINT:-http://minio:9000} TRACECAT__BLOB_STORAGE_SSL_VERIFY: ${TRACECAT__BLOB_STORAGE_SSL_VERIFY:-true} TRACECAT__BLOB_STORAGE_BUCKET_SKILLS: ${TRACECAT__BLOB_STORAGE_BUCKET_SKILLS:-tracecat-skills} MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} volumes: - ./tracecat:/app/tracecat - ./packages:/app/packages command: ["python", "-m", "tracecat.dsl.worker"] depends_on: migrations: condition: service_completed_successfully api: condition: service_started temporal: condition: service_healthy redis: condition: service_healthy minio: condition: service_healthy background-worker: build: context: . dockerfile: Dockerfile target: development restart: unless-stopped environment: TRACECAT__BACKGROUND_MAX_CONCURRENT_ACTIVITIES: ${TRACECAT__BACKGROUND_MAX_CONCURRENT_ACTIVITIES:-10} TRACECAT__AGENT_SANDBOX_TIMEOUT: ${TRACECAT__AGENT_SANDBOX_TIMEOUT:-10800} TRACECAT__CONTEXT_COMPRESSION_ENABLED: ${TRACECAT__CONTEXT_COMPRESSION_ENABLED:-false} TRACECAT__CONTEXT_COMPRESSION_THRESHOLD_KB: ${TRACECAT__CONTEXT_COMPRESSION_THRESHOLD_KB:-16} LOG_LEVEL: ${LOG_LEVEL} TRACECAT__LOG_FORMAT: ${TRACECAT__LOG_FORMAT:-console} TRACECAT__PLATFORM_OTEL_ENABLED: ${TRACECAT__PLATFORM_OTEL_ENABLED:-false} OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318} OTEL_TRACES_SAMPLER: ${OTEL_TRACES_SAMPLER:-parentbased_traceidratio} OTEL_TRACES_SAMPLER_ARG: ${OTEL_TRACES_SAMPLER_ARG:-1.0} OTEL_EXPORTER_OTLP_HEADERS: ${OTEL_EXPORTER_OTLP_HEADERS:-} TRACECAT__API_ROOT_PATH: ${TRACECAT__API_ROOT_PATH} TRACECAT__API_URL: ${TRACECAT__API_URL} TRACECAT__APP_ENV: ${TRACECAT__APP_ENV} TRACECAT__AWS_ASSUME_ROLE_ACCOUNT_ID: ${TRACECAT__AWS_ASSUME_ROLE_ACCOUNT_ID:-} TRACECAT__AWS_ASSUME_ROLE_PRINCIPAL_ARN: ${TRACECAT__AWS_ASSUME_ROLE_PRINCIPAL_ARN:-} TRACECAT__DB_ENCRYPTION_KEY: ${TRACECAT__DB_ENCRYPTION_KEY} # Sensitive TRACECAT__DB_SSLMODE: ${TRACECAT__DB_SSLMODE} TRACECAT__DB_URI: ${TRACECAT__DB_URI} # Sensitive TRACECAT__PUBLIC_API_URL: ${TRACECAT__PUBLIC_API_URL} TRACECAT__PUBLIC_APP_URL: ${TRACECAT__PUBLIC_APP_URL} TRACECAT__SERVICE_KEY: ${TRACECAT__SERVICE_KEY} # Sensitive TRACECAT__SERVICE_NAME: background-worker # Embedding provider calls from semantic-search indexing. TRACECAT__OUTBOUND_ALLOWED_PRIVATE_CIDRS: ${TRACECAT__OUTBOUND_ALLOWED_PRIVATE_CIDRS:-} TRACECAT__DB_POOL_TIMEOUT: ${TRACECAT__DB_POOL_TIMEOUT:-30} TRACECAT__DB_AUTH_POOL_SIZE: ${TRACECAT__DB_AUTH_POOL_SIZE:-5} TRACECAT__DB_AUTH_MAX_OVERFLOW: ${TRACECAT__DB_AUTH_MAX_OVERFLOW:-5} TRACECAT__SIGNING_SECRET: ${TRACECAT__SIGNING_SECRET} # Sensitive TRACECAT__FEATURE_FLAGS: ${TRACECAT__FEATURE_FLAGS} TRACECAT__EE_MULTI_TENANT: ${TRACECAT__EE_MULTI_TENANT:-false} TRACECAT__RESULT_EXTERNALIZATION_ENABLED: ${TRACECAT__RESULT_EXTERNALIZATION_ENABLED:-true} TRACECAT__COLLECTION_MANIFESTS_ENABLED: ${TRACECAT__COLLECTION_MANIFESTS_ENABLED:-true} TRACECAT__RESULT_EXTERNALIZATION_THRESHOLD_BYTES: ${TRACECAT__RESULT_EXTERNALIZATION_THRESHOLD_BYTES} TRACECAT__UNSAFE_DISABLE_SECRET_ERROR_WITHHOLDING: ${TRACECAT__UNSAFE_DISABLE_SECRET_ERROR_WITHHOLDING:-false} # Temporal TEMPORAL__CLUSTER_URL: ${TEMPORAL__CLUSTER_URL} TRACECAT__BACKGROUND_QUEUE: ${TRACECAT__BACKGROUND_QUEUE:-shared-background-queue} TEMPORAL__CLUSTER_QUEUE: ${TEMPORAL__CLUSTER_QUEUE} TEMPORAL__CLUSTER_NAMESPACE: ${TEMPORAL__CLUSTER_NAMESPACE} TEMPORAL__API_KEY: ${TEMPORAL__API_KEY} TEMPORAL__PAYLOAD_ENCRYPTION_ENABLED: ${TEMPORAL__PAYLOAD_ENCRYPTION_ENABLED:-false} TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING: ${TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING:-} TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING_ARN: ${TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING_ARN:-} TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_TTL_SECONDS: ${TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_TTL_SECONDS:-3600} TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_MAX_ITEMS: ${TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_MAX_ITEMS:-128} # Local registry TRACECAT__LOCAL_REPOSITORY_PATH: ${TRACECAT__LOCAL_REPOSITORY_PATH} TRACECAT__LOCAL_REPOSITORY_ENABLED: ${TRACECAT__LOCAL_REPOSITORY_ENABLED:-false} # Sentry SENTRY_DSN: ${SENTRY_DSN:-} # Redis REDIS_URL: ${REDIS_URL} # Blob storage (for S3) TRACECAT__BLOB_STORAGE_ENDPOINT: ${TRACECAT__BLOB_STORAGE_ENDPOINT:-http://minio:9000} TRACECAT__BLOB_STORAGE_SSL_VERIFY: ${TRACECAT__BLOB_STORAGE_SSL_VERIFY:-true} TRACECAT__BLOB_STORAGE_BUCKET_SKILLS: ${TRACECAT__BLOB_STORAGE_BUCKET_SKILLS:-tracecat-skills} MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} volumes: - ./tracecat:/app/tracecat - ./packages:/app/packages command: ["python", "-m", "tracecat.background.worker"] depends_on: migrations: condition: service_completed_successfully api: condition: service_started temporal: condition: service_healthy redis: condition: service_healthy minio: condition: service_healthy executor: build: context: . dockerfile: Dockerfile target: development restart: unless-stopped # Layer docker-compose.sandbox.yml when nsjail or SquashFS mount privileges # are needed locally. environment: # Common LOG_LEVEL: ${LOG_LEVEL} TRACECAT__LOG_FORMAT: ${TRACECAT__LOG_FORMAT:-console} TRACECAT__PLATFORM_OTEL_ENABLED: ${TRACECAT__PLATFORM_OTEL_ENABLED:-false} OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318} OTEL_TRACES_SAMPLER: ${OTEL_TRACES_SAMPLER:-parentbased_traceidratio} OTEL_TRACES_SAMPLER_ARG: ${OTEL_TRACES_SAMPLER_ARG:-1.0} TRACECAT__APP_ENV: ${TRACECAT__APP_ENV} TRACECAT__AWS_ASSUME_ROLE_ACCOUNT_ID: ${TRACECAT__AWS_ASSUME_ROLE_ACCOUNT_ID:-} TRACECAT__AWS_ASSUME_ROLE_PRINCIPAL_ARN: ${TRACECAT__AWS_ASSUME_ROLE_PRINCIPAL_ARN:-} TRACECAT__DB_ENCRYPTION_KEY: ${TRACECAT__DB_ENCRYPTION_KEY} # Sensitive TRACECAT__DB_SSLMODE: ${TRACECAT__DB_SSLMODE} TRACECAT__DB_URI: ${TRACECAT__DB_URI} # Sensitive TRACECAT__SERVICE_KEY: ${TRACECAT__SERVICE_KEY} # Sensitive TRACECAT__SERVICE_NAME: executor TRACECAT__AGENT_SANDBOX_TIMEOUT: ${TRACECAT__AGENT_SANDBOX_TIMEOUT:-10800} TRACECAT__DB_POOL_TIMEOUT: ${TRACECAT__DB_POOL_TIMEOUT:-30} TRACECAT__DB_AUTH_POOL_SIZE: ${TRACECAT__DB_AUTH_POOL_SIZE:-5} TRACECAT__DB_AUTH_MAX_OVERFLOW: ${TRACECAT__DB_AUTH_MAX_OVERFLOW:-5} TRACECAT__SIGNING_SECRET: ${TRACECAT__SIGNING_SECRET} # Sensitive TRACECAT__FEATURE_FLAGS: ${TRACECAT__FEATURE_FLAGS} TRACECAT__EE_MULTI_TENANT: ${TRACECAT__EE_MULTI_TENANT:-false} TRACECAT__API_URL: ${TRACECAT__API_URL:-http://api:8000} # Compression (must match worker for codec compatibility) TRACECAT__CONTEXT_COMPRESSION_ENABLED: ${TRACECAT__CONTEXT_COMPRESSION_ENABLED:-false} TRACECAT__CONTEXT_COMPRESSION_THRESHOLD_KB: ${TRACECAT__CONTEXT_COMPRESSION_THRESHOLD_KB:-16} TRACECAT__RESULT_EXTERNALIZATION_ENABLED: ${TRACECAT__RESULT_EXTERNALIZATION_ENABLED:-true} TRACECAT__COLLECTION_MANIFESTS_ENABLED: ${TRACECAT__COLLECTION_MANIFESTS_ENABLED:-true} TRACECAT__RESULT_EXTERNALIZATION_THRESHOLD_BYTES: ${TRACECAT__RESULT_EXTERNALIZATION_THRESHOLD_BYTES} # Registry TRACECAT__EXECUTOR_REGISTRY_CACHE_MAX_ENTRIES: ${TRACECAT__EXECUTOR_REGISTRY_CACHE_MAX_ENTRIES:-64} TRACECAT__EXECUTOR_REGISTRY_CACHE_MAX_BYTES: ${TRACECAT__EXECUTOR_REGISTRY_CACHE_MAX_BYTES:-10737418240} TRACECAT__UNSAFE_DISABLE_SM_MASKING: ${TRACECAT__UNSAFE_DISABLE_SM_MASKING:-false} TRACECAT__UNSAFE_DISABLE_SECRET_ERROR_WITHHOLDING: ${TRACECAT__UNSAFE_DISABLE_SECRET_ERROR_WITHHOLDING:-false} # Local registry TRACECAT__LOCAL_REPOSITORY_PATH: ${TRACECAT__LOCAL_REPOSITORY_PATH} TRACECAT__LOCAL_REPOSITORY_ENABLED: ${TRACECAT__LOCAL_REPOSITORY_ENABLED:-false} PYTHONPATH: ${PYTHONPATH:+${PYTHONPATH}:}/home/apiuser/.local:/app/local_registry # Sandbox # NOTE: *_ALLOWED_EGRESS_CIDRS gate private-network exceptions only; # the *_TCP_PORTS values apply to those CIDRs. Public IPv4 egress # remains unrestricted (any public IPv4, any port) regardless of the # allowed-egress CIDR settings. See tracecat/sandbox/networking.py. TRACECAT__SANDBOX_DEFAULT_MEMORY_MB: ${TRACECAT__SANDBOX_DEFAULT_MEMORY_MB:-2048} TRACECAT__SANDBOX_ADDRESS_SPACE_MB: ${TRACECAT__SANDBOX_ADDRESS_SPACE_MB:-} TRACECAT__SANDBOX_NSJAIL_PATH: /usr/local/bin/nsjail TRACECAT__SANDBOX_ROOTFS_PATH: /var/lib/tracecat/sandbox-rootfs TRACECAT__SANDBOX_CACHE_DIR: /var/lib/tracecat/sandbox-cache TRACECAT__REGISTRY_SYNC_CLONE_TIMEOUT: ${TRACECAT__REGISTRY_SYNC_CLONE_TIMEOUT:-120} TRACECAT__SANDBOX_INSTALL_ALLOWED_EGRESS_CIDRS: ${TRACECAT__SANDBOX_INSTALL_ALLOWED_EGRESS_CIDRS:-} TRACECAT__SANDBOX_INSTALL_ALLOWED_EGRESS_TCP_PORTS: ${TRACECAT__SANDBOX_INSTALL_ALLOWED_EGRESS_TCP_PORTS:-80,443} TRACECAT__SANDBOX_REGISTRY_ALLOWED_EGRESS_CIDRS: ${TRACECAT__SANDBOX_REGISTRY_ALLOWED_EGRESS_CIDRS:-} TRACECAT__SANDBOX_REGISTRY_ALLOWED_EGRESS_TCP_PORTS: ${TRACECAT__SANDBOX_REGISTRY_ALLOWED_EGRESS_TCP_PORTS:-22} TRACECAT__SANDBOX_SCRIPT_ALLOWED_EGRESS_CIDRS: ${TRACECAT__SANDBOX_SCRIPT_ALLOWED_EGRESS_CIDRS:-} TRACECAT__SANDBOX_SCRIPT_ALLOWED_EGRESS_TCP_PORTS: ${TRACECAT__SANDBOX_SCRIPT_ALLOWED_EGRESS_TCP_PORTS:-443} TRACECAT__SANDBOX_ACTION_ALLOWED_EGRESS_CIDRS: ${TRACECAT__SANDBOX_ACTION_ALLOWED_EGRESS_CIDRS:-} TRACECAT__SANDBOX_ACTION_ALLOWED_EGRESS_TCP_PORTS: ${TRACECAT__SANDBOX_ACTION_ALLOWED_EGRESS_TCP_PORTS:-443} TRACECAT__SANDBOX_AGENT_ALLOWED_EGRESS_CIDRS: ${TRACECAT__SANDBOX_AGENT_ALLOWED_EGRESS_CIDRS:-} TRACECAT__SANDBOX_AGENT_ALLOWED_EGRESS_TCP_PORTS: ${TRACECAT__SANDBOX_AGENT_ALLOWED_EGRESS_TCP_PORTS:-443} TRACECAT__SANDBOX_BLOCKED_EGRESS_CIDRS: ${TRACECAT__SANDBOX_BLOCKED_EGRESS_CIDRS:-} TRACECAT__SANDBOX_DNS_ALLOWED_EGRESS_CIDRS: ${TRACECAT__SANDBOX_DNS_ALLOWED_EGRESS_CIDRS:-} TRACECAT__SANDBOX_ALLOW_PUBLIC_IPV6_EGRESS: ${TRACECAT__SANDBOX_ALLOW_PUBLIC_IPV6_EGRESS:-false} # Temporal TEMPORAL__CLUSTER_URL: ${TEMPORAL__CLUSTER_URL} TEMPORAL__CLUSTER_NAMESPACE: ${TEMPORAL__CLUSTER_NAMESPACE} TEMPORAL__API_KEY: ${TEMPORAL__API_KEY} TEMPORAL__PAYLOAD_ENCRYPTION_ENABLED: ${TEMPORAL__PAYLOAD_ENCRYPTION_ENABLED:-false} TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING: ${TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING:-} TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING_ARN: ${TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING_ARN:-} TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_TTL_SECONDS: ${TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_TTL_SECONDS:-3600} TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_MAX_ITEMS: ${TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_MAX_ITEMS:-128} # Executor worker configuration TRACECAT__EXECUTOR_QUEUE: ${TRACECAT__EXECUTOR_QUEUE:-shared-action-queue} TRACECAT__EXECUTOR_BACKEND: ${TRACECAT__EXECUTOR_BACKEND:-direct} TRACECAT__EXECUTOR_MAX_CONCURRENT_ACTIVITIES: ${TRACECAT__EXECUTOR_MAX_CONCURRENT_ACTIVITIES:-32} TRACECAT__EXECUTOR_THREADPOOL_MAX_WORKERS: ${TRACECAT__EXECUTOR_THREADPOOL_MAX_WORKERS:-32} TRACECAT__EXECUTOR_FOR_EACH_MAX_CONCURRENCY: ${TRACECAT__EXECUTOR_FOR_EACH_MAX_CONCURRENCY:-4} # Sentry SENTRY_DSN: ${SENTRY_DSN:-} # Redis REDIS_URL: ${REDIS_URL} # Blob storage (for S3/MinIO wheel access) TRACECAT__BLOB_STORAGE_ENDPOINT: ${TRACECAT__BLOB_STORAGE_ENDPOINT:-http://minio:9000} TRACECAT__BLOB_STORAGE_SSL_VERIFY: ${TRACECAT__BLOB_STORAGE_SSL_VERIFY:-true} TRACECAT__BLOB_STORAGE_BUCKET_SKILLS: ${TRACECAT__BLOB_STORAGE_BUCKET_SKILLS:-tracecat-skills} MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} volumes: - ./tracecat:/app/tracecat - ./packages:/app/packages - ${TRACECAT__LOCAL_REPOSITORY_PATH}:/app/local_registry - sandbox-cache:/var/lib/tracecat/sandbox-cache command: ["python", "-m", "tracecat.executor.worker"] depends_on: migrations: condition: service_completed_successfully temporal: condition: service_healthy redis: condition: service_healthy minio: condition: service_healthy agent-worker: build: context: . dockerfile: Dockerfile target: development restart: unless-stopped environment: # Common LOG_LEVEL: ${LOG_LEVEL} TRACECAT__LOG_FORMAT: ${TRACECAT__LOG_FORMAT:-console} TRACECAT__PLATFORM_OTEL_ENABLED: ${TRACECAT__PLATFORM_OTEL_ENABLED:-false} OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318} OTEL_TRACES_SAMPLER: ${OTEL_TRACES_SAMPLER:-parentbased_traceidratio} OTEL_TRACES_SAMPLER_ARG: ${OTEL_TRACES_SAMPLER_ARG:-1.0} OTEL_EXPORTER_OTLP_HEADERS: ${OTEL_EXPORTER_OTLP_HEADERS:-} TRACECAT__APP_ENV: ${TRACECAT__APP_ENV} TRACECAT__AWS_ASSUME_ROLE_ACCOUNT_ID: ${TRACECAT__AWS_ASSUME_ROLE_ACCOUNT_ID:-} TRACECAT__AWS_ASSUME_ROLE_PRINCIPAL_ARN: ${TRACECAT__AWS_ASSUME_ROLE_PRINCIPAL_ARN:-} TRACECAT__DB_ENCRYPTION_KEY: ${TRACECAT__DB_ENCRYPTION_KEY} # Sensitive TRACECAT__DB_SSLMODE: ${TRACECAT__DB_SSLMODE} TRACECAT__DB_URI: ${TRACECAT__DB_URI} # Sensitive TRACECAT__SERVICE_KEY: ${TRACECAT__SERVICE_KEY} # Sensitive TRACECAT__SERVICE_NAME: agent-worker TRACECAT__AGENT_SANDBOX_TIMEOUT: ${TRACECAT__AGENT_SANDBOX_TIMEOUT:-10800} TRACECAT__DB_POOL_TIMEOUT: ${TRACECAT__DB_POOL_TIMEOUT:-30} TRACECAT__DB_AUTH_POOL_SIZE: ${TRACECAT__DB_AUTH_POOL_SIZE:-5} TRACECAT__DB_AUTH_MAX_OVERFLOW: ${TRACECAT__DB_AUTH_MAX_OVERFLOW:-5} TRACECAT__SIGNING_SECRET: ${TRACECAT__SIGNING_SECRET} # Sensitive TRACECAT__FEATURE_FLAGS: ${TRACECAT__FEATURE_FLAGS} TRACECAT__EE_MULTI_TENANT: ${TRACECAT__EE_MULTI_TENANT:-false} TRACECAT__API_URL: ${TRACECAT__API_URL:-http://api:8000} # Compression (must match worker for codec compatibility) TRACECAT__CONTEXT_COMPRESSION_ENABLED: ${TRACECAT__CONTEXT_COMPRESSION_ENABLED:-false} TRACECAT__CONTEXT_COMPRESSION_THRESHOLD_KB: ${TRACECAT__CONTEXT_COMPRESSION_THRESHOLD_KB:-16} TRACECAT__RESULT_EXTERNALIZATION_ENABLED: ${TRACECAT__RESULT_EXTERNALIZATION_ENABLED:-true} TRACECAT__COLLECTION_MANIFESTS_ENABLED: ${TRACECAT__COLLECTION_MANIFESTS_ENABLED:-true} TRACECAT__RESULT_EXTERNALIZATION_THRESHOLD_BYTES: ${TRACECAT__RESULT_EXTERNALIZATION_THRESHOLD_BYTES} # Registry TRACECAT__UNSAFE_DISABLE_SM_MASKING: ${TRACECAT__UNSAFE_DISABLE_SM_MASKING:-false} TRACECAT__UNSAFE_DISABLE_SECRET_ERROR_WITHHOLDING: ${TRACECAT__UNSAFE_DISABLE_SECRET_ERROR_WITHHOLDING:-false} # Temporal TEMPORAL__CLUSTER_URL: ${TEMPORAL__CLUSTER_URL} TEMPORAL__CLUSTER_NAMESPACE: ${TEMPORAL__CLUSTER_NAMESPACE} TEMPORAL__API_KEY: ${TEMPORAL__API_KEY} TEMPORAL__PAYLOAD_ENCRYPTION_ENABLED: ${TEMPORAL__PAYLOAD_ENCRYPTION_ENABLED:-false} TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING: ${TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING:-} TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING_ARN: ${TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING_ARN:-} TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_TTL_SECONDS: ${TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_TTL_SECONDS:-3600} TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_MAX_ITEMS: ${TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_MAX_ITEMS:-128} SENTRY_DSN: ${SENTRY_DSN:-} # Agent worker configuration TRACECAT__AGENT_QUEUE: ${TRACECAT__AGENT_QUEUE:-shared-agent-queue} TRACECAT__AGENT_EXECUTOR_QUEUE: ${TRACECAT__AGENT_EXECUTOR_QUEUE:-shared-agent-executor-queue} TRACECAT__EXECUTOR_QUEUE: ${TRACECAT__EXECUTOR_QUEUE:-shared-action-queue} TRACECAT__AGENT_MAX_CONCURRENT_ACTIVITIES: ${TRACECAT__AGENT_MAX_CONCURRENT_ACTIVITIES:-100} TEMPORAL__THREADPOOL_MAX_WORKERS: ${TEMPORAL__THREADPOOL_MAX_WORKERS:-100} TRACECAT__EXECUTOR_CLIENT_TIMEOUT: ${TRACECAT__EXECUTOR_CLIENT_TIMEOUT:-300} TRACECAT__LITELLM_BASE_URL: ${TRACECAT__LITELLM_BASE_URL:-http://litellm:4000} TRACECAT__OUTBOUND_ALLOWED_PRIVATE_CIDRS: ${TRACECAT__OUTBOUND_ALLOWED_PRIVATE_CIDRS:-} # Redis REDIS_URL: ${REDIS_URL} # Blob storage (for S3/MinIO tarball access) TRACECAT__BLOB_STORAGE_ENDPOINT: ${TRACECAT__BLOB_STORAGE_ENDPOINT:-http://minio:9000} TRACECAT__BLOB_STORAGE_SSL_VERIFY: ${TRACECAT__BLOB_STORAGE_SSL_VERIFY:-true} TRACECAT__BLOB_STORAGE_BUCKET_SKILLS: ${TRACECAT__BLOB_STORAGE_BUCKET_SKILLS:-tracecat-skills} MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} volumes: - ./tracecat:/app/tracecat - ./packages:/app/packages command: ["python", "-m", "tracecat.agent.worker"] depends_on: migrations: condition: service_completed_successfully api: condition: service_started temporal: condition: service_healthy redis: condition: service_healthy minio: condition: service_healthy litellm: build: context: . dockerfile: Dockerfile target: development restart: unless-stopped environment: LOG_LEVEL: ${LOG_LEVEL} TRACECAT__LOG_FORMAT: ${TRACECAT__LOG_FORMAT:-console} TRACECAT__APP_ENV: ${TRACECAT__APP_ENV} TRACECAT__DB_ENCRYPTION_KEY: ${TRACECAT__DB_ENCRYPTION_KEY} # Sensitive TRACECAT__DB_SSLMODE: ${TRACECAT__DB_SSLMODE} TRACECAT__DB_URI: ${TRACECAT__DB_URI} # Sensitive TRACECAT__SERVICE_KEY: ${TRACECAT__SERVICE_KEY} # Sensitive TRACECAT__SERVICE_NAME: litellm TRACECAT__DB_POOL_TIMEOUT: ${TRACECAT__DB_POOL_TIMEOUT:-30} TRACECAT__DB_AUTH_POOL_SIZE: ${TRACECAT__DB_AUTH_POOL_SIZE:-5} TRACECAT__DB_AUTH_MAX_OVERFLOW: ${TRACECAT__DB_AUTH_MAX_OVERFLOW:-5} TRACECAT__LITELLM_PORT: ${TRACECAT__LITELLM_PORT:-4000} # One proxy worker is enough locally; each worker holds ~300 MiB. TRACECAT__LITELLM_NUM_WORKERS: ${TRACECAT__LITELLM_NUM_WORKERS:-1} # Use LiteLLM's bundled model cost map instead of fetching it at startup. LITELLM_LOCAL_MODEL_COST_MAP: ${LITELLM_LOCAL_MODEL_COST_MAP:-true} TRACECAT__LITELLM_BASE_URL: ${TRACECAT__LITELLM_BASE_URL:-http://litellm:4000} TRACECAT__OUTBOUND_ALLOWED_PRIVATE_CIDRS: ${TRACECAT__OUTBOUND_ALLOWED_PRIVATE_CIDRS:-} PYTHONPATH: /app:/app/packages/tracecat-registry:/app/packages/tracecat-ee volumes: - ./tracecat:/app/tracecat - ./packages:/app/packages - ./alembic:/app/alembic command: ["python", "-m", "tracecat.agent.litellm"] depends_on: migrations: condition: service_completed_successfully healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:$${TRACECAT__LITELLM_PORT:-4000}/health/readiness"] interval: 5s timeout: 5s retries: 30 start_period: 10s agent-executor: build: context: . dockerfile: Dockerfile target: development restart: unless-stopped # Layer docker-compose.sandbox.yml when nsjail privileges are needed # locally. environment: # Common LOG_LEVEL: ${LOG_LEVEL} TRACECAT__LOG_FORMAT: ${TRACECAT__LOG_FORMAT:-console} TRACECAT__PLATFORM_OTEL_ENABLED: ${TRACECAT__PLATFORM_OTEL_ENABLED:-false} OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318} OTEL_TRACES_SAMPLER: ${OTEL_TRACES_SAMPLER:-parentbased_traceidratio} OTEL_TRACES_SAMPLER_ARG: ${OTEL_TRACES_SAMPLER_ARG:-1.0} TRACECAT__APP_ENV: ${TRACECAT__APP_ENV} TRACECAT__AWS_ASSUME_ROLE_ACCOUNT_ID: ${TRACECAT__AWS_ASSUME_ROLE_ACCOUNT_ID:-} TRACECAT__AWS_ASSUME_ROLE_PRINCIPAL_ARN: ${TRACECAT__AWS_ASSUME_ROLE_PRINCIPAL_ARN:-} TRACECAT__DB_ENCRYPTION_KEY: ${TRACECAT__DB_ENCRYPTION_KEY} # Sensitive TRACECAT__DB_SSLMODE: ${TRACECAT__DB_SSLMODE} TRACECAT__DB_URI: ${TRACECAT__DB_URI} # Sensitive TRACECAT__SERVICE_KEY: ${TRACECAT__SERVICE_KEY} # Sensitive TRACECAT__SERVICE_NAME: agent-executor SENTRY_DSN: ${SENTRY_DSN:-} TRACECAT__AGENT_SANDBOX_TIMEOUT: ${TRACECAT__AGENT_SANDBOX_TIMEOUT:-10800} TRACECAT__DB_POOL_TIMEOUT: ${TRACECAT__DB_POOL_TIMEOUT:-30} TRACECAT__DB_AUTH_POOL_SIZE: ${TRACECAT__DB_AUTH_POOL_SIZE:-5} TRACECAT__DB_AUTH_MAX_OVERFLOW: ${TRACECAT__DB_AUTH_MAX_OVERFLOW:-5} TRACECAT__SIGNING_SECRET: ${TRACECAT__SIGNING_SECRET} # Sensitive TRACECAT__FEATURE_FLAGS: ${TRACECAT__FEATURE_FLAGS} TRACECAT__EE_MULTI_TENANT: ${TRACECAT__EE_MULTI_TENANT:-false} TRACECAT__API_URL: ${TRACECAT__API_URL:-http://api:8000} TRACECAT__LITELLM_BASE_URL: ${TRACECAT__LITELLM_BASE_URL:-http://litellm:4000} TRACECAT__OUTBOUND_ALLOWED_PRIVATE_CIDRS: ${TRACECAT__OUTBOUND_ALLOWED_PRIVATE_CIDRS:-} # Compression (must match worker for codec compatibility) TRACECAT__CONTEXT_COMPRESSION_ENABLED: ${TRACECAT__CONTEXT_COMPRESSION_ENABLED:-false} TRACECAT__CONTEXT_COMPRESSION_THRESHOLD_KB: ${TRACECAT__CONTEXT_COMPRESSION_THRESHOLD_KB:-16} TRACECAT__RESULT_EXTERNALIZATION_ENABLED: ${TRACECAT__RESULT_EXTERNALIZATION_ENABLED:-true} TRACECAT__COLLECTION_MANIFESTS_ENABLED: ${TRACECAT__COLLECTION_MANIFESTS_ENABLED:-true} TRACECAT__RESULT_EXTERNALIZATION_THRESHOLD_BYTES: ${TRACECAT__RESULT_EXTERNALIZATION_THRESHOLD_BYTES} # Registry TRACECAT__EXECUTOR_REGISTRY_CACHE_MAX_ENTRIES: ${TRACECAT__EXECUTOR_REGISTRY_CACHE_MAX_ENTRIES:-64} TRACECAT__EXECUTOR_REGISTRY_CACHE_MAX_BYTES: ${TRACECAT__EXECUTOR_REGISTRY_CACHE_MAX_BYTES:-10737418240} TRACECAT__UNSAFE_DISABLE_SM_MASKING: ${TRACECAT__UNSAFE_DISABLE_SM_MASKING:-false} TRACECAT__UNSAFE_DISABLE_SECRET_ERROR_WITHHOLDING: ${TRACECAT__UNSAFE_DISABLE_SECRET_ERROR_WITHHOLDING:-false} # Local registry TRACECAT__LOCAL_REPOSITORY_PATH: ${TRACECAT__LOCAL_REPOSITORY_PATH} TRACECAT__LOCAL_REPOSITORY_ENABLED: ${TRACECAT__LOCAL_REPOSITORY_ENABLED:-false} PYTHONPATH: ${PYTHONPATH:+${PYTHONPATH}:}/home/apiuser/.local:/app/local_registry # Sandbox TRACECAT__EXECUTOR_BACKEND: ${TRACECAT__EXECUTOR_BACKEND:-direct} TRACECAT__SANDBOX_NSJAIL_PATH: /usr/local/bin/nsjail TRACECAT__SANDBOX_ROOTFS_PATH: /var/lib/tracecat/sandbox-rootfs TRACECAT__SANDBOX_CACHE_DIR: /var/lib/tracecat/sandbox-cache # NOTE: TRACECAT__SANDBOX_AGENT_ALLOWED_EGRESS_CIDRS gates # private-network exceptions only (ports apply to those CIDRs). With # empty CIDRs, public egress is unrestricted on all ports. TRACECAT__SANDBOX_AGENT_ALLOWED_EGRESS_CIDRS: ${TRACECAT__SANDBOX_AGENT_ALLOWED_EGRESS_CIDRS:-} TRACECAT__SANDBOX_AGENT_ALLOWED_EGRESS_TCP_PORTS: ${TRACECAT__SANDBOX_AGENT_ALLOWED_EGRESS_TCP_PORTS:-443} TRACECAT__SANDBOX_BLOCKED_EGRESS_CIDRS: ${TRACECAT__SANDBOX_BLOCKED_EGRESS_CIDRS:-} TRACECAT__SANDBOX_DNS_ALLOWED_EGRESS_CIDRS: ${TRACECAT__SANDBOX_DNS_ALLOWED_EGRESS_CIDRS:-} TRACECAT__SANDBOX_ALLOW_PUBLIC_IPV6_EGRESS: ${TRACECAT__SANDBOX_ALLOW_PUBLIC_IPV6_EGRESS:-false} # Temporal TEMPORAL__CLUSTER_URL: ${TEMPORAL__CLUSTER_URL} TEMPORAL__CLUSTER_NAMESPACE: ${TEMPORAL__CLUSTER_NAMESPACE} TEMPORAL__API_KEY: ${TEMPORAL__API_KEY} TEMPORAL__PAYLOAD_ENCRYPTION_ENABLED: ${TEMPORAL__PAYLOAD_ENCRYPTION_ENABLED:-false} TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING: ${TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING:-} TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING_ARN: ${TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING_ARN:-} TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_TTL_SECONDS: ${TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_TTL_SECONDS:-3600} TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_MAX_ITEMS: ${TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_MAX_ITEMS:-128} # Agent worker configuration TRACECAT__AGENT_QUEUE: ${TRACECAT__AGENT_QUEUE:-shared-agent-queue} TRACECAT__AGENT_EXECUTOR_QUEUE: ${TRACECAT__AGENT_EXECUTOR_QUEUE:-shared-agent-executor-queue} TRACECAT__EXECUTOR_QUEUE: ${TRACECAT__EXECUTOR_QUEUE:-shared-action-queue} TRACECAT__AGENT_EXECUTOR_MAX_CONCURRENT_ACTIVITIES: ${TRACECAT__AGENT_EXECUTOR_MAX_CONCURRENT_ACTIVITIES:-8} TRACECAT__AGENT_SANDBOX_MEMORY_MB: ${TRACECAT__AGENT_SANDBOX_MEMORY_MB:-4096} TRACECAT__AGENT_SANDBOX_ADDRESS_SPACE_MB: ${TRACECAT__AGENT_SANDBOX_ADDRESS_SPACE_MB:-} # Keep the thread pool aligned with agent activity concurrency. TEMPORAL__THREADPOOL_MAX_WORKERS: ${TRACECAT__AGENT_EXECUTOR_MAX_CONCURRENT_ACTIVITIES:-8} TRACECAT__LLM_PROXY_READ_TIMEOUT: ${TRACECAT__LLM_PROXY_READ_TIMEOUT:-600} TRACECAT__LLM_GATEWAY_CREDENTIAL_CACHE_TTL_SECONDS: ${TRACECAT__LLM_GATEWAY_CREDENTIAL_CACHE_TTL_SECONDS:-60} TRACECAT__LLM_GATEWAY_HEALTHCHECK_INTERVAL_SECONDS: ${TRACECAT__LLM_GATEWAY_HEALTHCHECK_INTERVAL_SECONDS:-30} TRACECAT__LLM_GATEWAY_HEALTHCHECK_TIMEOUT_SECONDS: ${TRACECAT__LLM_GATEWAY_HEALTHCHECK_TIMEOUT_SECONDS:-2} TRACECAT__LLM_GATEWAY_CONNECT_TIMEOUT_SECONDS: ${TRACECAT__LLM_GATEWAY_CONNECT_TIMEOUT_SECONDS:-} TRACECAT__LLM_GATEWAY_READ_TIMEOUT_SECONDS: ${TRACECAT__LLM_GATEWAY_READ_TIMEOUT_SECONDS:-} TRACECAT__LLM_GATEWAY_WRITE_TIMEOUT_SECONDS: ${TRACECAT__LLM_GATEWAY_WRITE_TIMEOUT_SECONDS:-} TRACECAT__LLM_GATEWAY_POOL_TIMEOUT_SECONDS: ${TRACECAT__LLM_GATEWAY_POOL_TIMEOUT_SECONDS:-} TRACECAT__LLM_GATEWAY_FAILURE_THRESHOLD: ${TRACECAT__LLM_GATEWAY_FAILURE_THRESHOLD:-3} TRACECAT__LLM_GATEWAY_STATUS_LOG_INTERVAL_SECONDS: ${TRACECAT__LLM_GATEWAY_STATUS_LOG_INTERVAL_SECONDS:-30} # Redis REDIS_URL: ${REDIS_URL} # Blob storage (for S3/MinIO tarball access) TRACECAT__BLOB_STORAGE_ENDPOINT: ${TRACECAT__BLOB_STORAGE_ENDPOINT:-http://minio:9000} TRACECAT__BLOB_STORAGE_SSL_VERIFY: ${TRACECAT__BLOB_STORAGE_SSL_VERIFY:-true} TRACECAT__BLOB_STORAGE_BUCKET_SKILLS: ${TRACECAT__BLOB_STORAGE_BUCKET_SKILLS:-tracecat-skills} MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} volumes: - ./tracecat:/app/tracecat - ./packages:/app/packages - ${TRACECAT__LOCAL_REPOSITORY_PATH}:/app/local_registry - sandbox-cache:/var/lib/tracecat/sandbox-cache command: ["python", "-m", "tracecat.agent.executor_worker"] depends_on: litellm: condition: service_healthy migrations: condition: service_completed_successfully api: condition: service_started temporal: condition: service_healthy redis: condition: service_healthy minio: condition: service_healthy mcp: build: context: . dockerfile: Dockerfile target: development restart: on-failure:3 environment: TRACECAT__AUDIT_TRUSTED_PROXY_CIDRS: ${TRACECAT__AUDIT_TRUSTED_PROXY_CIDRS:-} LOG_LEVEL: ${LOG_LEVEL} TRACECAT__LOG_FORMAT: ${TRACECAT__LOG_FORMAT:-console} TRACECAT__APP_ENV: ${TRACECAT__APP_ENV} TRACECAT__DB_ENCRYPTION_KEY: ${TRACECAT__DB_ENCRYPTION_KEY} TRACECAT__DB_SSLMODE: ${TRACECAT__DB_SSLMODE} TRACECAT__DB_URI: ${TRACECAT__DB_URI} TRACECAT__SERVICE_KEY: ${TRACECAT__SERVICE_KEY} TRACECAT__SERVICE_NAME: mcp TRACECAT__AGENT_SANDBOX_TIMEOUT: ${TRACECAT__AGENT_SANDBOX_TIMEOUT:-10800} TRACECAT__DB_POOL_TIMEOUT: ${TRACECAT__DB_POOL_TIMEOUT:-30} TRACECAT__DB_AUTH_POOL_SIZE: ${TRACECAT__DB_AUTH_POOL_SIZE:-5} TRACECAT__DB_AUTH_MAX_OVERFLOW: ${TRACECAT__DB_AUTH_MAX_OVERFLOW:-5} TRACECAT__SIGNING_SECRET: ${TRACECAT__SIGNING_SECRET} TRACECAT__FEATURE_FLAGS: ${TRACECAT__FEATURE_FLAGS} TRACECAT__EE_MULTI_TENANT: ${TRACECAT__EE_MULTI_TENANT:-false} # Redis REDIS_URL: ${REDIS_URL} # Internal OIDC issuer (on the API server) USER_AUTH_SECRET: ${USER_AUTH_SECRET} TRACECAT__API_URL: ${TRACECAT__API_URL:-http://api:8000} TRACECAT__PUBLIC_APP_URL: ${TRACECAT__PUBLIC_APP_URL} TRACECAT__PUBLIC_API_URL: ${TRACECAT__PUBLIC_API_URL:-http://localhost:${PUBLIC_APP_PORT:-80}/api} # MCP-specific TRACECAT_MCP__FILE_TRANSFER_URL_EXPIRY_SECONDS: ${TRACECAT_MCP__FILE_TRANSFER_URL_EXPIRY_SECONDS:-300} TRACECAT_MCP__STARTUP_MAX_ATTEMPTS: ${TRACECAT_MCP__STARTUP_MAX_ATTEMPTS:-3} TRACECAT_MCP__STARTUP_RETRY_DELAY_SECONDS: ${TRACECAT_MCP__STARTUP_RETRY_DELAY_SECONDS:-2} # Temporal TEMPORAL__CLUSTER_URL: ${TEMPORAL__CLUSTER_URL} TRACECAT__BACKGROUND_QUEUE: ${TRACECAT__BACKGROUND_QUEUE:-shared-background-queue} TEMPORAL__CLUSTER_QUEUE: ${TEMPORAL__CLUSTER_QUEUE} TEMPORAL__CLUSTER_NAMESPACE: ${TEMPORAL__CLUSTER_NAMESPACE} TEMPORAL__API_KEY: ${TEMPORAL__API_KEY} TEMPORAL__PAYLOAD_ENCRYPTION_ENABLED: ${TEMPORAL__PAYLOAD_ENCRYPTION_ENABLED:-false} TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING: ${TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING:-} TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING_ARN: ${TEMPORAL__PAYLOAD_ENCRYPTION_KEYRING_ARN:-} TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_TTL_SECONDS: ${TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_TTL_SECONDS:-3600} TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_MAX_ITEMS: ${TEMPORAL__PAYLOAD_ENCRYPTION_CACHE_MAX_ITEMS:-128} # Blob Storage TRACECAT__BLOB_STORAGE_ENDPOINT: ${TRACECAT__BLOB_STORAGE_ENDPOINT:-http://minio:9000} TRACECAT__BLOB_STORAGE_SSL_VERIFY: ${TRACECAT__BLOB_STORAGE_SSL_VERIFY:-true} TRACECAT__BLOB_STORAGE_BUCKET_SKILLS: ${TRACECAT__BLOB_STORAGE_BUCKET_SKILLS:-tracecat-skills} TRACECAT__BLOB_STORAGE_PRESIGNED_URL_ENDPOINT: ${TRACECAT__BLOB_STORAGE_PRESIGNED_URL_ENDPOINT:-${TRACECAT__PUBLIC_APP_URL}/s3} MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} volumes: - ./tracecat:/app/tracecat - ./packages:/app/packages command: ["python", "-m", "tracecat.mcp"] depends_on: api: condition: service_healthy migrations: condition: service_completed_successfully temporal: condition: service_healthy minio: condition: service_healthy redis: condition: service_healthy ui: # image: ghcr.io/tracecathq/tracecat-ui:${TRACECAT__IMAGE_TAG:-latest} # container_name: ui build: context: ./frontend dockerfile: Dockerfile args: NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL} NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL} NEXT_SERVER_API_URL: ${NEXT_SERVER_API_URL} NODE_ENV: ${NODE_ENV} volumes: - ./frontend/src:/app/src - ./frontend/.next:/app/.next - ./frontend/node_modules:/app/node_modules restart: unless-stopped ports: - ${UI_PORT:-3000}:3000 environment: NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL} NEXT_PUBLIC_APP_ENV: ${NEXT_PUBLIC_APP_ENV} NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL} NEXT_PUBLIC_AUTH_TYPES: ${TRACECAT__AUTH_TYPES} NEXT_SERVER_API_URL: ${NEXT_SERVER_API_URL} NODE_ENV: ${NODE_ENV} TRACECAT__CSP_CONNECT_SRC_ORIGINS: ${TRACECAT__CSP_CONNECT_SRC_ORIGINS:-${TRACECAT__BLOB_STORAGE_PRESIGNED_URL_ENDPOINT:-${TRACECAT__PUBLIC_APP_URL}/s3}} TRACECAT__SERVICE_KEY: ${TRACECAT__SERVICE_KEY} attach: false depends_on: - api postgres_db: image: ${TRACECAT__PGVECTOR_IMAGE:-ghcr.io/tracecathq/tracecat-postgres:1} command: ["postgres"] restart: unless-stopped ports: - ${PG_PORT:-5432}:5432 shm_size: 128mb environment: POSTGRES_DB: postgres POSTGRES_USER: ${TRACECAT__POSTGRES_USER} POSTGRES_PASSWORD: ${TRACECAT__POSTGRES_PASSWORD} volumes: - core-db:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U $${POSTGRES_USER} -d postgres"] interval: 5s timeout: 5s retries: 12 start_period: 180s migrations: build: context: . dockerfile: Dockerfile target: development restart: "no" environment: LOG_LEVEL: ${LOG_LEVEL} TRACECAT__LOG_FORMAT: ${TRACECAT__LOG_FORMAT:-console} # The app's database: role setup checks it names the admin URI's database. TRACECAT__DB_URI: ${TRACECAT__DB_URI} # Sensitive # Migrations log in as migrator once database role setup is on. TRACECAT__DB_MIGRATOR_URI: ${TRACECAT__DB_MIGRATOR_URI:-} # Sensitive # With TRACECAT__DB_ROLE_LOGIN set, role setup runs as TRACECAT__DB_ADMIN_URI first. TRACECAT__DB_ADMIN_URI: ${TRACECAT__DB_ADMIN_URI:-} # Sensitive TRACECAT__DB_MIGRATOR_PASSWORD: ${TRACECAT__DB_MIGRATOR_PASSWORD:-} # Sensitive TRACECAT__DB_APP_PASSWORD: ${TRACECAT__DB_APP_PASSWORD:-} # Sensitive TRACECAT__DB_ROLE_LOGIN: ${TRACECAT__DB_ROLE_LOGIN:-} TRACECAT__DB_SSLMODE: ${TRACECAT__DB_SSLMODE} TRACECAT__FEATURE_FLAGS: ${TRACECAT__FEATURE_FLAGS} volumes: - ./tracecat:/app/tracecat - ./packages:/app/packages - ./alembic:/app/alembic # Role setup (when on) as the admin, then migrations as migrator. command: - sh - -ec - | if [ -n "$${TRACECAT__DB_ROLE_LOGIN}" ]; then python3 -m tracecat.db.roles upgrade --login "$${TRACECAT__DB_ROLE_LOGIN}" fi # The migrations get migrator's login only, never the admin's. ( unset TRACECAT__DB_ADMIN_URI TRACECAT__DB_MIGRATOR_PASSWORD TRACECAT__DB_APP_PASSWORD if [ -n "$${TRACECAT__DB_MIGRATOR_URI}" ]; then export TRACECAT__DB_URI="$${TRACECAT__DB_MIGRATOR_URI}" fi exec python3 -m tracecat.db.roles migrate ) # Again once the schema exists: installs the dynamic-table RLS guard on a new install. if [ -n "$${TRACECAT__DB_ROLE_LOGIN}" ]; then python3 -m tracecat.db.roles upgrade --login "$${TRACECAT__DB_ROLE_LOGIN}" fi depends_on: postgres_db: condition: service_healthy temporal_postgres_db: image: postgres:13 restart: unless-stopped environment: POSTGRES_USER: ${TEMPORAL__POSTGRES_USER} POSTGRES_PASSWORD: ${TEMPORAL__POSTGRES_PASSWORD} volumes: - temporal-db:/var/lib/postgresql/data temporal: image: temporalio/auto-setup:${TEMPORAL__VERSION:-1.27.1} restart: unless-stopped ports: - ${TEMPORAL_PORT:-7233}:7233 environment: - DB=postgres12 - DB_PORT=5432 - POSTGRES_USER=${TEMPORAL__POSTGRES_USER} - POSTGRES_PWD=${TEMPORAL__POSTGRES_PASSWORD} - POSTGRES_SEEDS=temporal_postgres_db - DEFAULT_NAMESPACE_RETENTION=${TEMPORAL__DEFAULT_NAMESPACE_RETENTION:-24h} - LOG_LEVEL=warn healthcheck: test: ["CMD", "tctl", "--address", "temporal:7233", "cluster", "health"] interval: 5s timeout: 10s retries: 30 depends_on: - temporal_postgres_db attach: false temporal_ui: image: temporalio/ui:${TEMPORAL__UI_VERSION:-latest} ports: - ${TEMPORAL_UI_PORT:-8081}:8080 environment: - TEMPORAL_ADDRESS=temporal:7233 - TEMPORAL_CORS_ORIGINS=http://localhost:${TEMPORAL_UI_PORT:-8081} depends_on: - temporal attach: false minio-init: image: cgr.dev/chainguard/minio:latest@sha256:6a1d0b45c8669726bba580ced0bfa4cb9fdeed1ed636dfabd81d1577beb6937b user: "0:0" entrypoint: ["chown", "-R", "65532:65532", "/data"] volumes: - minio-data:/data network_mode: none restart: "no" attach: false minio: image: cgr.dev/chainguard/minio:latest@sha256:6a1d0b45c8669726bba580ced0bfa4cb9fdeed1ed636dfabd81d1577beb6937b restart: unless-stopped ports: - ${MINIO_PORT:-9000}:9000 - ${MINIO_CONSOLE_PORT:-9001}:9001 environment: MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} volumes: - minio-data:/data command: server /data --console-address ":9001" depends_on: minio-init: condition: service_completed_successfully healthcheck: test: ["CMD", "mc", "ready", "local"] interval: 5s timeout: 5s retries: 5 attach: false redis: image: redis:7-alpine restart: unless-stopped ports: - ${REDIS_PORT_HOST:-6379}:6379 volumes: - redis-data:/data command: redis-server --appendonly yes healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 5s retries: 5 attach: false volumes: core-db: temporal-db: containers: minio-data: redis-data: sandbox-cache: