# dd0c Local Development Stack # # Usage: docker compose up -d # All services share one Postgres and one Redis instance. # Caddy handles TLS and routing for *.dd0c.localhost services: # --- Shared Infrastructure --- postgres: image: postgres:16-alpine environment: POSTGRES_USER: ${POSTGRES_USER:-dd0c} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-dd0c-dev} DB_DRIFT_PASSWORD: ${DB_DRIFT_PASSWORD:-dd0c-dev} DB_ALERT_PASSWORD: ${DB_ALERT_PASSWORD:-dd0c-dev} DB_PORTAL_PASSWORD: ${DB_PORTAL_PASSWORD:-dd0c-dev} DB_COST_PASSWORD: ${DB_COST_PASSWORD:-dd0c-dev} DB_RUN_PASSWORD: ${DB_RUN_PASSWORD:-dd0c-dev} ports: - "5433:5432" volumes: - pg_data:/var/lib/postgresql/data - ./docker-init-db.sh:/docker-entrypoint-initdb.d/01-init-db.sh:ro - ./01-llm-cost-router/migrations:/migrations/01-route:ro - ./02-iac-drift-detection/saas/migrations:/migrations/02-drift:ro - ./03-alert-intelligence/migrations:/migrations/03-alert:ro - ./04-lightweight-idp/migrations:/migrations/04-portal:ro - ./05-aws-cost-anomaly/migrations:/migrations/05-cost:ro - ./06-runbook-automation/saas/migrations:/migrations/06-run:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U dd0c"] interval: 5s timeout: 3s retries: 5 redis: image: redis:7-alpine ports: - "6379:6379" healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 meilisearch: image: getmeili/meilisearch:v1.8 environment: MEILI_ENV: development ports: - "7700:7700" volumes: - meili_data:/meili_data # --- dd0c Products --- # P1: LLM Cost Router (Rust — API server) # NOTE: Rust services are behind the "rust" profile because they take 10+ min to compile. # Start without Rust: docker compose up -d # Start with Rust: docker compose --profile rust up -d route-api: profiles: ["rust"] build: context: ./01-llm-cost-router dockerfile: Dockerfile command: ["dd0c-api"] ports: - "3001:3000" environment: NODE_ENV: production PORT: "3000" DATABASE_URL: postgresql://dd0c:${POSTGRES_PASSWORD:-dd0c-dev}@postgres:5432/dd0c_route REDIS_URL: redis://redis:6379 JWT_SECRET: ${JWT_SECRET:-dev-secret-change-me-in-production!!} LOG_LEVEL: info depends_on: postgres: { condition: service_healthy } redis: { condition: service_healthy } # P1: LLM Cost Router (Rust — proxy) route-proxy: profiles: ["rust"] build: context: ./01-llm-cost-router dockerfile: Dockerfile command: ["dd0c-proxy"] ports: - "8080:8080" environment: DATABASE_URL: postgresql://dd0c:${POSTGRES_PASSWORD:-dd0c-dev}@postgres:5432/dd0c_route REDIS_URL: redis://redis:6379 LOG_LEVEL: info depends_on: postgres: { condition: service_healthy } redis: { condition: service_healthy } # P1: LLM Cost Router (Rust — worker) route-worker: profiles: ["rust"] build: context: ./01-llm-cost-router dockerfile: Dockerfile command: ["dd0c-worker"] environment: DATABASE_URL: postgresql://dd0c:${POSTGRES_PASSWORD:-dd0c-dev}@postgres:5432/dd0c_route REDIS_URL: redis://redis:6379 LOG_LEVEL: info depends_on: postgres: { condition: service_healthy } redis: { condition: service_healthy } # P2: IaC Drift Detection (SaaS) drift: image: reg.dd0c.net/dd0c-drift:latest build: context: ./02-iac-drift-detection/saas dockerfile: Dockerfile ports: - "3002:3000" environment: NODE_ENV: production PORT: "3000" DATABASE_URL: postgresql://dd0c_drift:${DB_DRIFT_PASSWORD:-dd0c-dev}@postgres:5432/dd0c_drift REDIS_URL: redis://redis:6379 JWT_SECRET: ${JWT_SECRET:-dev-secret-change-me-in-production!!} LOG_LEVEL: info depends_on: postgres: { condition: service_healthy } redis: { condition: service_healthy } # P3: Alert Intelligence alert: image: reg.dd0c.net/dd0c-alert:latest build: context: ./03-alert-intelligence dockerfile: Dockerfile ports: - "3003:3000" environment: NODE_ENV: production PORT: "3000" DATABASE_URL: postgresql://dd0c_alert:${DB_ALERT_PASSWORD:-dd0c-dev}@postgres:5432/dd0c_alert REDIS_URL: redis://redis:6379 JWT_SECRET: ${JWT_SECRET:-dev-secret-change-me-in-production!!} LOG_LEVEL: info depends_on: postgres: { condition: service_healthy } redis: { condition: service_healthy } # P4: Lightweight IDP / Service Catalog portal: image: reg.dd0c.net/dd0c-portal:latest build: context: ./04-lightweight-idp dockerfile: Dockerfile ports: - "3004:3000" environment: NODE_ENV: production PORT: "3000" DATABASE_URL: postgresql://dd0c_portal:${DB_PORTAL_PASSWORD:-dd0c-dev}@postgres:5432/dd0c_portal REDIS_URL: redis://redis:6379 MEILI_URL: http://meilisearch:7700 JWT_SECRET: ${JWT_SECRET:-dev-secret-change-me-in-production!!} LOG_LEVEL: info depends_on: postgres: { condition: service_healthy } redis: { condition: service_healthy } meilisearch: { condition: service_started } # P5: AWS Cost Anomaly Detection cost: image: reg.dd0c.net/dd0c-cost:latest build: context: ./05-aws-cost-anomaly dockerfile: Dockerfile ports: - "3007:3000" environment: NODE_ENV: production PORT: "3000" DATABASE_URL: postgresql://dd0c_cost:${DB_COST_PASSWORD:-dd0c-dev}@postgres:5432/dd0c_cost REDIS_URL: redis://redis:6379 JWT_SECRET: ${JWT_SECRET:-dev-secret-change-me-in-production!!} ANOMALY_THRESHOLD: "50" LOG_LEVEL: info depends_on: postgres: { condition: service_healthy } redis: { condition: service_healthy } # P6: Runbook Automation (SaaS) run: image: reg.dd0c.net/dd0c-run:latest build: context: ./06-runbook-automation/saas dockerfile: Dockerfile ports: - "3006:3000" environment: NODE_ENV: production PORT: "3000" DATABASE_URL: postgresql://dd0c_run:${DB_RUN_PASSWORD:-dd0c-dev}@postgres:5432/dd0c_run REDIS_URL: redis://redis:6379 JWT_SECRET: ${JWT_SECRET:-dev-secret-change-me-in-production!!} LOG_LEVEL: info depends_on: postgres: { condition: service_healthy } redis: { condition: service_healthy } # dd0c Console (React SPA) console: image: reg.dd0c.net/dd0c-console:latest build: context: ./console dockerfile: Dockerfile ports: - "3010:80" # dd0c Marketing Site (Astro) marketing: image: reg.dd0c.net/dd0c-marketing:latest build: context: ./marketing/site dockerfile: Dockerfile ports: - "3011:80" volumes: pg_data: meili_data: