194 lines
10 KiB
YAML
194 lines
10 KiB
YAML
# docker-compose.den-dev.yml — Den local testability stack
|
|
#
|
|
# Usage (from repo root):
|
|
# docker compose -f packaging/docker/docker-compose.den-dev.yml up
|
|
#
|
|
# Then open the printed web UI or Den demo URL.
|
|
#
|
|
# Env overrides (optional, via export or .env):
|
|
# DEN_API_PORT — host port to map to Den control plane :8788
|
|
# DEN_WEB_PORT — host port to map to the cloud web app :3005
|
|
# DEN_MYSQL_PORT — host port to map to MySQL :3306
|
|
# DEN_BETTER_AUTH_SECRET — Better Auth secret (auto-generated by den-dev-up.sh)
|
|
# DEN_DB_ENCRYPTION_KEY — dev-only DB encryption key for encrypted columns
|
|
# — defaults to a premade local key for Docker smoke tests
|
|
# — generate a replacement with: openssl rand -base64 128
|
|
# DEN_PUBLIC_HOST — browser-facing host/IP for LAN access (set by den-dev-up.sh)
|
|
# DEN_BETTER_AUTH_URL — browser-facing auth origin (default: http://<DEN_PUBLIC_HOST>:<DEN_WEB_PORT>)
|
|
# DEN_BETTER_AUTH_TRUSTED_ORIGINS — Better Auth trusted origins (defaults to DEN_CORS_ORIGINS)
|
|
# DEN_MCP_ADDITIONAL_RESOURCES — Extra public MCP resource URLs this deployment serves, e.g. https://api.openworklabs.com/mcp — needed when den-api is reachable on more than one public origin
|
|
# DEN_CORS_ORIGINS — comma-separated trusted origins for Better Auth + CORS
|
|
# DEN_ORG_MODE — single_org or multi_org (default: single_org)
|
|
# DEN_SINGLE_ORG_NAME / DEN_SINGLE_ORG_SLUG / DEN_SINGLE_ORG_OWNER_EMAILS
|
|
# — singleton organization defaults for local private-mode testing
|
|
# DEN_INITIAL_ADMIN_BOOTSTRAP_CODE / DEN_INITIAL_ADMIN_BOOTSTRAP_CODE_FILE
|
|
# — optional one-time /setup code for private zero-user deployments
|
|
# DEN_PROVISIONER_MODE — stub, render, or daytona (default: stub)
|
|
# DEN_WORKER_URL_TEMPLATE — worker URL template used by stub provisioning
|
|
# DAYTONA_API_URL / DAYTONA_API_KEY / DAYTONA_TARGET / DAYTONA_SNAPSHOT
|
|
# — optional Daytona passthrough vars when DEN_PROVISIONER_MODE=daytona
|
|
# POLAR_FEATURE_GATE_ENABLED / POLAR_API_BASE / POLAR_ACCESS_TOKEN
|
|
# POLAR_PRODUCT_ID / POLAR_BENEFIT_ID / POLAR_SUCCESS_URL / POLAR_RETURN_URL
|
|
# — optional Polar passthrough vars for billing/paywall testing
|
|
# DEN_OBSERVABILITY_BACKEND — none, otel, or sentry (default: none)
|
|
# OTEL_EXPORTER_OTLP_ENDPOINT — OTLP/HTTP base endpoint for den + web, e.g. http://otel-lgtm:4318
|
|
# OTEL_EXPORTER_OTLP_TRACES_ENDPOINT / OTEL_EXPORTER_OTLP_METRICS_ENDPOINT / OTEL_EXPORTER_OTLP_LOGS_ENDPOINT
|
|
# — optional per-signal OTLP/HTTP endpoint overrides
|
|
# OTEL_EXPORTER_OTLP_HEADERS — optional OTLP header string, e.g. Authorization=Bearer token
|
|
# OTEL_EXPORTER_OTLP_PROTOCOL — only http/protobuf is supported (default: http/protobuf)
|
|
# OTEL_EXPORTER_OTLP_TRACES_PROTOCOL / OTEL_EXPORTER_OTLP_METRICS_PROTOCOL / OTEL_EXPORTER_OTLP_LOGS_PROTOCOL
|
|
# — optional per-signal protocol overrides, only http/protobuf is supported
|
|
# OTEL_TRACES_EXPORTER / OTEL_METRICS_EXPORTER / OTEL_LOGS_EXPORTER
|
|
# — otlp or none per signal (default: otlp)
|
|
# OTEL_TRACES_SAMPLER / OTEL_TRACES_SAMPLER_ARG
|
|
# — standard OpenTelemetry sampler controls
|
|
# SENTRY_DSN / SENTRY_TRACES_SAMPLE_RATE / SENTRY_ENVIRONMENT / SENTRY_RELEASE / SENTRY_DIST
|
|
# — optional Sentry runtime settings (source-map upload is build-time only)
|
|
# DEN_AUTOMATIONS_POLL_INTERVAL_MS and friends
|
|
# — tune Den's always-on in-process Automation loop
|
|
|
|
x-shared: &shared
|
|
restart: unless-stopped
|
|
|
|
x-observability-env: &observability-env
|
|
DEN_OBSERVABILITY_BACKEND: ${DEN_OBSERVABILITY_BACKEND:-none}
|
|
OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-}
|
|
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: ${OTEL_EXPORTER_OTLP_TRACES_ENDPOINT:-}
|
|
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: ${OTEL_EXPORTER_OTLP_METRICS_ENDPOINT:-}
|
|
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: ${OTEL_EXPORTER_OTLP_LOGS_ENDPOINT:-}
|
|
OTEL_EXPORTER_OTLP_HEADERS: ${OTEL_EXPORTER_OTLP_HEADERS:-}
|
|
OTEL_EXPORTER_OTLP_PROTOCOL: ${OTEL_EXPORTER_OTLP_PROTOCOL:-http/protobuf}
|
|
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL: ${OTEL_EXPORTER_OTLP_TRACES_PROTOCOL:-}
|
|
OTEL_EXPORTER_OTLP_METRICS_PROTOCOL: ${OTEL_EXPORTER_OTLP_METRICS_PROTOCOL:-}
|
|
OTEL_EXPORTER_OTLP_LOGS_PROTOCOL: ${OTEL_EXPORTER_OTLP_LOGS_PROTOCOL:-}
|
|
OTEL_TRACES_EXPORTER: ${OTEL_TRACES_EXPORTER:-otlp}
|
|
OTEL_METRICS_EXPORTER: ${OTEL_METRICS_EXPORTER:-otlp}
|
|
OTEL_LOGS_EXPORTER: ${OTEL_LOGS_EXPORTER:-otlp}
|
|
OTEL_TRACES_SAMPLER: ${OTEL_TRACES_SAMPLER:-parentbased_always_on}
|
|
OTEL_TRACES_SAMPLER_ARG: ${OTEL_TRACES_SAMPLER_ARG:-}
|
|
SENTRY_DSN: ${SENTRY_DSN:-}
|
|
SENTRY_TRACES_SAMPLE_RATE: ${SENTRY_TRACES_SAMPLE_RATE:-0.01}
|
|
SENTRY_LOG_LEVEL: ${SENTRY_LOG_LEVEL:-warn}
|
|
SENTRY_ENVIRONMENT: ${SENTRY_ENVIRONMENT:-}
|
|
SENTRY_RELEASE: ${SENTRY_RELEASE:-}
|
|
SENTRY_DIST: ${SENTRY_DIST:-}
|
|
|
|
services:
|
|
mysql:
|
|
image: mysql:8.4
|
|
command:
|
|
- --performance_schema=OFF
|
|
- --innodb-buffer-pool-size=64M
|
|
- --innodb-log-buffer-size=8M
|
|
- --tmp-table-size=16M
|
|
- --max-heap-table-size=16M
|
|
environment:
|
|
MYSQL_ROOT_PASSWORD: password
|
|
MYSQL_DATABASE: openwork_den
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -ppassword --silent"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 30
|
|
start_period: 10s
|
|
ports:
|
|
- "${DEN_MYSQL_PORT:-3306}:3306"
|
|
volumes:
|
|
- den-mysql-data:/var/lib/mysql
|
|
|
|
den:
|
|
<<: *shared
|
|
build:
|
|
context: ../../
|
|
dockerfile: packaging/docker/Dockerfile.den
|
|
command: ["sh", "-lc", "cd /app/ee/packages/den-db && yes | node --import tsx ./node_modules/drizzle-kit/bin.cjs push --config drizzle.config.ts && node /app/ee/apps/den-api/dist/main.js"]
|
|
depends_on:
|
|
mysql:
|
|
condition: service_healthy
|
|
ports:
|
|
- "${DEN_API_PORT:-8788}:8788"
|
|
healthcheck:
|
|
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:8788/health').then((res)=>process.exit(res.ok?0:1)).catch(()=>process.exit(1))"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 30
|
|
start_period: 120s
|
|
environment:
|
|
<<: *observability-env
|
|
CI: "true"
|
|
OPENWORK_DEV_MODE: ${OPENWORK_DEV_MODE:-1}
|
|
OTEL_SERVICE_NAME: ${DEN_API_OTEL_SERVICE_NAME:-den-api}
|
|
DATABASE_URL: mysql://root:password@mysql:3306/openwork_den
|
|
BETTER_AUTH_SECRET: ${DEN_BETTER_AUTH_SECRET:-dev-den-local-auth-secret-please-override-1234567890}
|
|
DEN_DB_ENCRYPTION_KEY: ${DEN_DB_ENCRYPTION_KEY:-dev-den-db-encryption-key-please-change-1234567890}
|
|
BETTER_AUTH_URL: ${DEN_BETTER_AUTH_URL:-http://localhost:3005}
|
|
DEN_ORG_MODE: ${DEN_ORG_MODE:-single_org}
|
|
DEN_SINGLE_ORG_NAME: ${DEN_SINGLE_ORG_NAME:-OpenWork}
|
|
DEN_SINGLE_ORG_SLUG: ${DEN_SINGLE_ORG_SLUG:-default}
|
|
DEN_SINGLE_ORG_OWNER_EMAILS: ${DEN_SINGLE_ORG_OWNER_EMAILS:-}
|
|
DEN_SINGLE_ORG_ALLOW_PUBLIC_SIGNUP: ${DEN_SINGLE_ORG_ALLOW_PUBLIC_SIGNUP:-false}
|
|
DEN_INITIAL_ADMIN_BOOTSTRAP_CODE: ${DEN_INITIAL_ADMIN_BOOTSTRAP_CODE:-}
|
|
DEN_INITIAL_ADMIN_BOOTSTRAP_CODE_FILE: ${DEN_INITIAL_ADMIN_BOOTSTRAP_CODE_FILE:-}
|
|
DEN_SINGLE_ORG_ALLOW_EMAIL_PASSWORD_AFTER_SSO: ${DEN_SINGLE_ORG_ALLOW_EMAIL_PASSWORD_AFTER_SSO:-false}
|
|
DEN_REQUIRE_EMAIL_VERIFICATION: ${DEN_REQUIRE_EMAIL_VERIFICATION:-false}
|
|
DEN_MCP_RESOURCE_URL: ${DEN_MCP_RESOURCE_URL:-http://localhost:8788/mcp}
|
|
DEN_MCP_ADDITIONAL_RESOURCES: ${DEN_MCP_ADDITIONAL_RESOURCES:-}
|
|
DEN_API_PUBLIC_URL: ${DEN_API_PUBLIC_URL:-http://localhost:8788}
|
|
DEN_BETTER_AUTH_TRUSTED_ORIGINS: ${DEN_BETTER_AUTH_TRUSTED_ORIGINS:-}
|
|
PORT: "8788"
|
|
CORS_ORIGINS: ${DEN_CORS_ORIGINS:-http://localhost:3005,http://127.0.0.1:3005,http://0.0.0.0:3005,http://localhost:5173,http://127.0.0.1:5173,http://localhost:8788,http://127.0.0.1:8788}
|
|
PROVISIONER_MODE: ${DEN_PROVISIONER_MODE:-stub}
|
|
WORKER_URL_TEMPLATE: ${DEN_WORKER_URL_TEMPLATE:-}
|
|
POLAR_FEATURE_GATE_ENABLED: ${POLAR_FEATURE_GATE_ENABLED:-false}
|
|
POLAR_API_BASE: ${POLAR_API_BASE:-}
|
|
POLAR_ACCESS_TOKEN: ${POLAR_ACCESS_TOKEN:-}
|
|
POLAR_PRODUCT_ID: ${POLAR_PRODUCT_ID:-}
|
|
POLAR_BENEFIT_ID: ${POLAR_BENEFIT_ID:-}
|
|
POLAR_SUCCESS_URL: ${POLAR_SUCCESS_URL:-}
|
|
POLAR_RETURN_URL: ${POLAR_RETURN_URL:-}
|
|
DAYTONA_API_URL: ${DAYTONA_API_URL:-}
|
|
DAYTONA_API_KEY: ${DAYTONA_API_KEY:-}
|
|
DAYTONA_TARGET: ${DAYTONA_TARGET:-}
|
|
DAYTONA_SNAPSHOT: ${DAYTONA_SNAPSHOT:-}
|
|
DEN_AUTOMATIONS_POLL_INTERVAL_MS: ${DEN_AUTOMATIONS_POLL_INTERVAL_MS:-15000}
|
|
DEN_AUTOMATIONS_BATCH_SIZE: ${DEN_AUTOMATIONS_BATCH_SIZE:-25}
|
|
DEN_AUTOMATIONS_MAX_CONCURRENCY: ${DEN_AUTOMATIONS_MAX_CONCURRENCY:-4}
|
|
DEN_AUTOMATIONS_LEASE_MS: ${DEN_AUTOMATIONS_LEASE_MS:-60000}
|
|
DEN_AUTOMATIONS_RUN_TIMEOUT_MS: ${DEN_AUTOMATIONS_RUN_TIMEOUT_MS:-900000}
|
|
DEN_AUTOMATIONS_RUNNER_CLAIM_DEADLINE_MS: ${DEN_AUTOMATIONS_RUNNER_CLAIM_DEADLINE_MS:-60000}
|
|
|
|
web:
|
|
<<: *shared
|
|
build:
|
|
context: ../../
|
|
dockerfile: packaging/docker/Dockerfile.den-web
|
|
depends_on:
|
|
den:
|
|
condition: service_healthy
|
|
ports:
|
|
- "${DEN_WEB_PORT:-3005}:3005"
|
|
healthcheck:
|
|
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:3005/api/health').then((res)=>process.exit(res.ok?0:1)).catch(()=>process.exit(1))"]
|
|
interval: 5s
|
|
timeout: 10s
|
|
retries: 30
|
|
start_period: 180s
|
|
environment:
|
|
<<: *observability-env
|
|
CI: "true"
|
|
OPENWORK_DEV_MODE: "1"
|
|
OTEL_SERVICE_NAME: ${DEN_WEB_OTEL_SERVICE_NAME:-den-web}
|
|
DEN_API_BASE: http://den:8788
|
|
DEN_AUTH_FALLBACK_BASE: http://den:8788
|
|
DEN_AUTH_ORIGIN: ${DEN_BETTER_AUTH_URL:-http://localhost:3005}
|
|
DEN_WEB_PUBLIC_ORIGIN: ${DEN_BETTER_AUTH_URL:-http://localhost:3005}
|
|
DEN_WEB_OPENWORK_AUTH_CALLBACK_URL: ${DEN_BETTER_AUTH_URL:-http://localhost:3005}
|
|
DEN_ORG_MODE: ${DEN_ORG_MODE:-single_org}
|
|
DEN_SINGLE_ORG_NAME: ${DEN_SINGLE_ORG_NAME:-OpenWork}
|
|
DEN_SINGLE_ORG_SLUG: ${DEN_SINGLE_ORG_SLUG:-default}
|
|
DEN_SINGLE_ORG_ALLOW_PUBLIC_SIGNUP: ${DEN_SINGLE_ORG_ALLOW_PUBLIC_SIGNUP:-false}
|
|
DEN_SINGLE_ORG_ALLOW_EMAIL_PASSWORD_AFTER_SSO: ${DEN_SINGLE_ORG_ALLOW_EMAIL_PASSWORD_AFTER_SSO:-false}
|
|
|
|
volumes:
|
|
den-mysql-data:
|