# ========================================================= # BreakPilot Compliance — Compliance SDK Platform (Coolify) # ========================================================= # Requires: breakpilot-core must be running # Deployed via Coolify. SSL termination handled by Traefik. # External services (managed separately in Coolify): # - PostgreSQL, Qdrant, S3-compatible storage # ========================================================= networks: breakpilot-network: external: true name: breakpilot-network volumes: dsms_data: services: # ========================================================= # FRONTEND # ========================================================= admin-compliance: build: context: ./admin-compliance dockerfile: Dockerfile args: NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-https://api-compliance.breakpilot.ai} NEXT_PUBLIC_SDK_URL: ${NEXT_PUBLIC_SDK_URL:-https://sdk.breakpilot.ai} container_name: bp-compliance-admin expose: - "3000" environment: NODE_ENV: production BACKEND_URL: http://backend-compliance:8002 CONSENT_SERVICE_URL: http://bp-core-consent-service:8081 SDK_URL: http://ai-compliance-sdk:8090 OLLAMA_URL: ${OLLAMA_URL:-} COMPLIANCE_LLM_MODEL: ${COMPLIANCE_LLM_MODEL:-} depends_on: backend-compliance: condition: service_started labels: - "traefik.enable=true" - "traefik.http.routers.admin-compliance.rule=Host(`admin-compliance.breakpilot.ai`)" - "traefik.http.routers.admin-compliance.entrypoints=https" - "traefik.http.routers.admin-compliance.tls=true" - "traefik.http.routers.admin-compliance.tls.certresolver=letsencrypt" - "traefik.http.services.admin-compliance.loadbalancer.server.port=3000" restart: unless-stopped networks: - breakpilot-network developer-portal: build: context: ./developer-portal dockerfile: Dockerfile container_name: bp-compliance-developer-portal expose: - "3000" environment: NODE_ENV: production labels: - "traefik.enable=true" - "traefik.http.routers.developer-portal.rule=Host(`developer.breakpilot.ai`)" - "traefik.http.routers.developer-portal.entrypoints=https" - "traefik.http.routers.developer-portal.tls=true" - "traefik.http.routers.developer-portal.tls.certresolver=letsencrypt" - "traefik.http.services.developer-portal.loadbalancer.server.port=3000" restart: unless-stopped networks: - breakpilot-network # ========================================================= # BACKEND # ========================================================= backend-compliance: build: context: ./backend-compliance dockerfile: Dockerfile container_name: bp-compliance-backend expose: - "8002" environment: PORT: 8002 DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT:-5432}/${POSTGRES_DB}?options=-csearch_path%3Dcompliance,core,public JWT_SECRET: ${JWT_SECRET} ENVIRONMENT: production CONSENT_SERVICE_URL: http://bp-core-consent-service:8081 VALKEY_URL: redis://bp-core-valkey:6379/0 SESSION_TTL_HOURS: ${SESSION_TTL_HOURS:-24} COMPLIANCE_LLM_PROVIDER: ${COMPLIANCE_LLM_PROVIDER:-anthropic} SELF_HOSTED_LLM_URL: ${SELF_HOSTED_LLM_URL:-} SELF_HOSTED_LLM_MODEL: ${SELF_HOSTED_LLM_MODEL:-} COMPLIANCE_LLM_MAX_TOKENS: ${COMPLIANCE_LLM_MAX_TOKENS:-4096} COMPLIANCE_LLM_TEMPERATURE: ${COMPLIANCE_LLM_TEMPERATURE:-0.3} COMPLIANCE_LLM_TIMEOUT: ${COMPLIANCE_LLM_TIMEOUT:-120} ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-} SMTP_HOST: ${SMTP_HOST} SMTP_PORT: ${SMTP_PORT:-587} SMTP_USERNAME: ${SMTP_USERNAME} SMTP_PASSWORD: ${SMTP_PASSWORD} SMTP_FROM_NAME: ${SMTP_FROM_NAME:-BreakPilot Compliance} SMTP_FROM_ADDR: ${SMTP_FROM_ADDR:-compliance@breakpilot.ai} RAG_SERVICE_URL: http://bp-core-rag-service:8097 labels: - "traefik.enable=true" - "traefik.http.routers.backend-compliance.rule=Host(`api-compliance.breakpilot.ai`)" - "traefik.http.routers.backend-compliance.entrypoints=https" - "traefik.http.routers.backend-compliance.tls=true" - "traefik.http.routers.backend-compliance.tls.certresolver=letsencrypt" - "traefik.http.services.backend-compliance.loadbalancer.server.port=8002" restart: unless-stopped networks: - breakpilot-network # ========================================================= # SDK SERVICES # ========================================================= ai-compliance-sdk: build: context: ./ai-compliance-sdk dockerfile: Dockerfile container_name: bp-compliance-ai-sdk expose: - "8090" environment: PORT: 8090 ENVIRONMENT: production DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT:-5432}/${POSTGRES_DB} JWT_SECRET: ${JWT_SECRET} LLM_PROVIDER: ${COMPLIANCE_LLM_PROVIDER:-anthropic} LLM_FALLBACK_PROVIDER: ${LLM_FALLBACK_PROVIDER:-} OLLAMA_URL: ${OLLAMA_URL:-} OLLAMA_DEFAULT_MODEL: ${OLLAMA_DEFAULT_MODEL:-} ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-} ANTHROPIC_DEFAULT_MODEL: ${ANTHROPIC_DEFAULT_MODEL:-claude-sonnet-4-5-20250929} PII_REDACTION_ENABLED: ${PII_REDACTION_ENABLED:-true} PII_REDACTION_LEVEL: ${PII_REDACTION_LEVEL:-standard} AUDIT_RETENTION_DAYS: ${AUDIT_RETENTION_DAYS:-365} AUDIT_LOG_PROMPTS: ${AUDIT_LOG_PROMPTS:-true} ALLOWED_ORIGINS: "*" TTS_SERVICE_URL: http://compliance-tts-service:8095 QDRANT_HOST: ${QDRANT_HOST} QDRANT_PORT: ${QDRANT_PORT:-6333} healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:8090/health"] interval: 30s timeout: 3s start_period: 10s retries: 3 labels: - "traefik.enable=true" - "traefik.http.routers.ai-sdk.rule=Host(`sdk.breakpilot.ai`)" - "traefik.http.routers.ai-sdk.entrypoints=https" - "traefik.http.routers.ai-sdk.tls=true" - "traefik.http.routers.ai-sdk.tls.certresolver=letsencrypt" - "traefik.http.services.ai-sdk.loadbalancer.server.port=8090" restart: unless-stopped networks: - breakpilot-network # ========================================================= # TTS SERVICE (Piper TTS + FFmpeg) # ========================================================= compliance-tts-service: build: context: ./compliance-tts-service dockerfile: Dockerfile container_name: bp-compliance-tts expose: - "8095" environment: MINIO_ENDPOINT: ${S3_ENDPOINT} MINIO_ACCESS_KEY: ${S3_ACCESS_KEY} MINIO_SECRET_KEY: ${S3_SECRET_KEY} PIPER_MODEL_PATH: /app/models/de_DE-thorsten-high.onnx healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8095/health')"] interval: 30s timeout: 10s start_period: 60s retries: 3 restart: unless-stopped networks: - breakpilot-network # ========================================================= # DATA SOVEREIGNTY # ========================================================= dsms-node: build: context: ./dsms-node dockerfile: Dockerfile container_name: bp-compliance-dsms-node expose: - "4001" - "5001" - "8080" volumes: - dsms_data:/data/ipfs environment: IPFS_PROFILE: server healthcheck: test: ["CMD-SHELL", "ipfs id"] interval: 30s timeout: 10s start_period: 30s retries: 3 restart: unless-stopped networks: - breakpilot-network dsms-gateway: build: context: ./dsms-gateway dockerfile: Dockerfile container_name: bp-compliance-dsms-gateway expose: - "8082" environment: IPFS_API_URL: http://dsms-node:5001 IPFS_GATEWAY_URL: http://dsms-node:8080 JWT_SECRET: ${JWT_SECRET} depends_on: dsms-node: condition: service_healthy restart: unless-stopped networks: - breakpilot-network # ========================================================= # DOCUMENT CRAWLER & AUTO-ONBOARDING # ========================================================= document-crawler: build: context: ./document-crawler dockerfile: Dockerfile container_name: bp-compliance-document-crawler expose: - "8098" environment: PORT: 8098 DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT:-5432}/${POSTGRES_DB} LLM_GATEWAY_URL: http://ai-compliance-sdk:8090 DSMS_GATEWAY_URL: http://dsms-gateway:8082 CRAWL_BASE_PATH: /data/crawl MAX_FILE_SIZE_MB: 50 volumes: - /tmp/breakpilot-crawl-data:/data/crawl:ro healthcheck: test: ["CMD", "curl", "-f", "http://127.0.0.1:8098/health"] interval: 30s timeout: 10s start_period: 15s retries: 3 restart: unless-stopped networks: - breakpilot-network