# ========================================================= # BreakPilot Lehrer — KI-Lehrerplattform # ========================================================= # Voraussetzung: breakpilot-core muss laufen! # Start: docker compose up -d # ========================================================= networks: breakpilot-network: external: true name: breakpilot-network volumes: klausur_uploads: eh_uploads: ocr_labeling: paddle_models: paddleocr_models: voice_session_data: geo_osm_data: geo_dem_data: geo_tile_cache: geo_aoi_bundles: transcription_models: transcription_temp: lehrer_backend_data: services: # ========================================================= # CORE HEALTH CHECK — wartet auf Core-Infrastruktur # ========================================================= core-health-check: image: curlimages/curl:latest container_name: bp-lehrer-core-wait command: > sh -c " echo 'Waiting for Core infrastructure...' until curl -sf http://bp-core-health:8099/health; do echo 'Core not ready, waiting 5s...' sleep 5 done echo 'Core is healthy!' " restart: "no" networks: - breakpilot-network # ========================================================= # FRONTEND # ========================================================= admin-lehrer: build: context: ./admin-lehrer dockerfile: Dockerfile args: NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-https://macmini:8001} NEXT_PUBLIC_OLD_ADMIN_URL: ${NEXT_PUBLIC_OLD_ADMIN_URL:-http://macmini:3000/admin} NEXT_PUBLIC_KLAUSUR_SERVICE_URL: ${NEXT_PUBLIC_KLAUSUR_SERVICE_URL:-https://macmini:8086} NEXT_PUBLIC_VOICE_SERVICE_URL: ${NEXT_PUBLIC_VOICE_SERVICE_URL:-wss://macmini:8091} container_name: bp-lehrer-admin platform: linux/arm64 expose: - "3000" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - lehrer_backend_data:/app/data environment: NODE_ENV: production BACKEND_URL: http://backend-lehrer:8001 CONSENT_SERVICE_URL: http://bp-core-consent-service:8081 KLAUSUR_SERVICE_URL: http://klausur-service:8086 OLLAMA_URL: ${OLLAMA_URL:-http://host.docker.internal:11434} WOODPECKER_URL: http://bp-core-woodpecker-server:8000 WOODPECKER_TOKEN: ${WOODPECKER_TOKEN:-} extra_hosts: - "host.docker.internal:host-gateway" depends_on: core-health-check: condition: service_completed_successfully backend-lehrer: condition: service_started restart: unless-stopped networks: - breakpilot-network studio-v2: build: context: ./studio-v2 dockerfile: Dockerfile args: NEXT_PUBLIC_VOICE_SERVICE_URL: ${NEXT_PUBLIC_VOICE_SERVICE_URL:-wss://macmini:8091} NEXT_PUBLIC_KLAUSUR_SERVICE_URL: ${NEXT_PUBLIC_KLAUSUR_SERVICE_URL:-https://macmini:8086} container_name: bp-lehrer-studio-v2 platform: linux/arm64 ports: - "3001:3001" - "3004:3001" environment: NODE_ENV: production BACKEND_URL: http://backend-lehrer:8001 depends_on: - backend-lehrer restart: unless-stopped networks: - breakpilot-network website: build: context: ./website dockerfile: Dockerfile args: NEXT_PUBLIC_BILLING_API_URL: ${NEXT_PUBLIC_BILLING_API_URL:-https://macmini:8083} NEXT_PUBLIC_APP_URL: ${NEXT_PUBLIC_APP_URL:-https://macmini} NEXT_PUBLIC_KLAUSUR_SERVICE_URL: ${NEXT_PUBLIC_KLAUSUR_SERVICE_URL:-https://macmini:8086} NEXT_PUBLIC_VOICE_SERVICE_URL: ${NEXT_PUBLIC_VOICE_SERVICE_URL:-wss://macmini:8091} NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: ${NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY:-} container_name: bp-lehrer-website platform: linux/arm64 expose: - "3000" environment: NODE_ENV: production VAST_API_KEY: ${VAST_API_KEY:-} CONTROL_API_KEY: ${CONTROL_API_KEY:-} BACKEND_URL: http://backend-lehrer:8001 CONSENT_SERVICE_URL: http://bp-core-consent-service:8081 EDU_SEARCH_URL: ${EDU_SEARCH_URL:-} EDU_SEARCH_API_KEY: ${EDU_SEARCH_API_KEY:-} WOODPECKER_URL: http://bp-core-woodpecker-server:8000 WOODPECKER_TOKEN: ${WOODPECKER_TOKEN:-} depends_on: - backend-lehrer restart: unless-stopped networks: - breakpilot-network # ========================================================= # BACKEND # ========================================================= backend-lehrer: build: context: ./backend-lehrer dockerfile: Dockerfile container_name: bp-lehrer-backend user: "0:0" platform: linux/arm64 expose: - "8001" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - lehrer_backend_data:/app/data environment: PORT: 8001 DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-breakpilot}:${POSTGRES_PASSWORD:-breakpilot123}@bp-core-postgres:5432/${POSTGRES_DB:-breakpilot_db}?options=-csearch_path%3Dlehrer,core,public JWT_SECRET: ${JWT_SECRET:-your-super-secret-jwt-key-change-in-production} ENVIRONMENT: ${ENVIRONMENT:-development} CONSENT_SERVICE_URL: http://bp-core-consent-service:8081 KLAUSUR_SERVICE_URL: http://klausur-service:8086 TROCR_SERVICE_URL: http://paddleocr-service:8095 CAMUNDA_URL: http://bp-core-camunda:8080 VALKEY_URL: redis://bp-core-valkey:6379/0 SESSION_TTL_HOURS: ${SESSION_TTL_HOURS:-24} ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-} DEBUG: ${DEBUG:-false} ALERTS_AGENT_ENABLED: ${ALERTS_AGENT_ENABLED:-false} VAULT_ADDR: http://bp-core-vault:8200 VAULT_TOKEN: ${VAULT_TOKEN:-breakpilot-dev-token} USE_VAULT_SECRETS: ${USE_VAULT_SECRETS:-false} VAST_API_KEY: ${VAST_API_KEY:-} VAST_INSTANCE_ID: ${VAST_INSTANCE_ID:-} CONTROL_API_KEY: ${CONTROL_API_KEY:-} OLLAMA_BASE_URL: ${OLLAMA_BASE_URL:-http://host.docker.internal:11434} OLLAMA_ENABLED: ${OLLAMA_ENABLED:-true} OLLAMA_DEFAULT_MODEL: ${OLLAMA_DEFAULT_MODEL:-llama3.2} OLLAMA_VISION_MODEL: ${OLLAMA_VISION_MODEL:-llama3.2-vision} OLLAMA_CORRECTION_MODEL: ${OLLAMA_CORRECTION_MODEL:-llama3.2} OLLAMA_TIMEOUT: ${OLLAMA_TIMEOUT:-120} GAME_USE_DATABASE: ${GAME_USE_DATABASE:-true} GAME_REQUIRE_AUTH: ${GAME_REQUIRE_AUTH:-false} GAME_REQUIRE_BILLING: ${GAME_REQUIRE_BILLING:-false} GAME_LLM_MODEL: ${GAME_LLM_MODEL:-llama3.2} SMTP_HOST: ${SMTP_HOST:-bp-core-mailpit} SMTP_PORT: ${SMTP_PORT:-1025} SMTP_USERNAME: ${SMTP_USERNAME:-} SMTP_PASSWORD: ${SMTP_PASSWORD:-} SMTP_FROM_NAME: ${SMTP_FROM_NAME:-BreakPilot} SMTP_FROM_ADDR: ${SMTP_FROM_ADDR:-noreply@breakpilot.app} RAG_SERVICE_URL: http://bp-core-rag-service:8097 extra_hosts: - "host.docker.internal:host-gateway" - "mac-mini:192.168.178.163" depends_on: core-health-check: condition: service_completed_successfully restart: unless-stopped networks: - breakpilot-network # ========================================================= # MICROSERVICES # ========================================================= klausur-service: build: context: ./klausur-service dockerfile: Dockerfile container_name: bp-lehrer-klausur-service platform: linux/arm64 expose: - "8086" volumes: - klausur_uploads:/app/uploads - eh_uploads:/app/eh-uploads - ocr_labeling:/app/ocr-labeling - paddle_models:/root/.paddlex environment: JWT_SECRET: ${JWT_SECRET:-your-super-secret-jwt-key-change-in-production} BACKEND_URL: http://backend-lehrer:8001 SCHOOL_SERVICE_URL: http://school-service:8084 ENVIRONMENT: ${ENVIRONMENT:-development} DATABASE_URL: postgresql://${POSTGRES_USER:-breakpilot}:${POSTGRES_PASSWORD:-breakpilot123}@bp-core-postgres:5432/${POSTGRES_DB:-breakpilot_db} EMBEDDING_SERVICE_URL: http://bp-core-embedding-service:8087 QDRANT_URL: http://bp-core-qdrant:6333 MINIO_ENDPOINT: bp-core-minio:9000 MINIO_ACCESS_KEY: ${MINIO_ROOT_USER:-breakpilot} MINIO_SECRET_KEY: ${MINIO_ROOT_PASSWORD:-breakpilot123} MINIO_BUCKET: ${MINIO_BUCKET:-breakpilot-rag} MINIO_SECURE: "false" PADDLEOCR_SERVICE_URL: http://paddleocr-service:8095 VAULT_ADDR: http://bp-core-vault:8200 VAULT_TOKEN: ${VAULT_TOKEN:-breakpilot-dev-token} ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-} OLLAMA_BASE_URL: ${OLLAMA_BASE_URL:-http://host.docker.internal:11434} OLLAMA_ENABLED: ${OLLAMA_ENABLED:-true} OLLAMA_DEFAULT_MODEL: ${OLLAMA_DEFAULT_MODEL:-llama3.2} OLLAMA_VISION_MODEL: ${OLLAMA_VISION_MODEL:-llama3.2-vision} OLLAMA_CORRECTION_MODEL: ${OLLAMA_CORRECTION_MODEL:-llama3.2} RAG_SERVICE_URL: http://bp-core-rag-service:8097 extra_hosts: - "host.docker.internal:host-gateway" depends_on: core-health-check: condition: service_completed_successfully school-service: condition: service_started healthcheck: test: ["CMD", "curl", "-f", "http://127.0.0.1:8086/health"] interval: 30s timeout: 30s retries: 3 start_period: 10s restart: unless-stopped networks: - breakpilot-network school-service: build: context: ./school-service dockerfile: Dockerfile container_name: bp-lehrer-school-service platform: linux/arm64 ports: - "8084:8084" environment: DATABASE_URL: postgresql://${POSTGRES_USER:-breakpilot}:${POSTGRES_PASSWORD:-breakpilot123}@bp-core-postgres:5432/${POSTGRES_DB:-breakpilot_db} JWT_SECRET: ${JWT_SECRET:-your-super-secret-jwt-key-change-in-production} PORT: 8084 ENVIRONMENT: ${ENVIRONMENT:-development} ALLOWED_ORIGINS: "*" LLM_GATEWAY_URL: http://backend-lehrer:8001/llm depends_on: core-health-check: condition: service_completed_successfully restart: unless-stopped networks: - breakpilot-network geo-service: build: context: ./geo-service dockerfile: Dockerfile container_name: bp-lehrer-geo-service platform: linux/arm64 ports: - "8088:8088" volumes: - geo_osm_data:/app/data/osm - geo_dem_data:/app/data/dem - geo_tile_cache:/app/cache/tiles - geo_aoi_bundles:/app/bundles environment: PORT: 8088 ENVIRONMENT: ${ENVIRONMENT:-development} JWT_SECRET: ${JWT_SECRET:-your-super-secret-jwt-key-change-in-production} DATABASE_URL: postgresql://${POSTGRES_USER:-breakpilot}:${POSTGRES_PASSWORD:-breakpilot123}@bp-core-postgres:5432/${POSTGRES_DB:-breakpilot_db} MINIO_ENDPOINT: bp-core-minio:9000 MINIO_ACCESS_KEY: ${MINIO_ROOT_USER:-breakpilot} MINIO_SECRET_KEY: ${MINIO_ROOT_PASSWORD:-breakpilot123} MINIO_BUCKET: ${MINIO_BUCKET:-breakpilot-geo} MINIO_SECURE: "false" OLLAMA_BASE_URL: ${OLLAMA_BASE_URL:-http://host.docker.internal:11434} OLLAMA_MODEL: ${OLLAMA_DEFAULT_MODEL:-llama3.2} TILE_CACHE_DIR: /app/cache/tiles DEM_CACHE_DIR: /app/data/dem MAX_AOI_SIZE_KM2: ${MAX_AOI_SIZE_KM2:-100} extra_hosts: - "host.docker.internal:host-gateway" depends_on: core-health-check: condition: service_completed_successfully healthcheck: test: ["CMD", "curl", "-f", "http://127.0.0.1:8088/health"] interval: 30s timeout: 10s start_period: 60s retries: 3 restart: unless-stopped networks: - breakpilot-network voice-service: build: context: ./voice-service dockerfile: Dockerfile container_name: bp-lehrer-voice-service platform: linux/arm64 expose: - "8091" volumes: - voice_session_data:/app/data/sessions environment: PORT: 8091 DATABASE_URL: postgresql://${POSTGRES_USER:-breakpilot}:${POSTGRES_PASSWORD:-breakpilot123}@bp-core-postgres:5432/${POSTGRES_DB:-breakpilot_db} VALKEY_URL: redis://bp-core-valkey:6379/0 KLAUSUR_SERVICE_URL: http://klausur-service:8086 OLLAMA_BASE_URL: ${OLLAMA_BASE_URL:-http://host.docker.internal:11434} OLLAMA_VOICE_MODEL: ${OLLAMA_VOICE_MODEL:-llama3.2} ENVIRONMENT: ${ENVIRONMENT:-development} JWT_SECRET: ${JWT_SECRET:-your-super-secret-jwt-key-change-in-production} extra_hosts: - "host.docker.internal:host-gateway" depends_on: core-health-check: condition: service_completed_successfully healthcheck: test: ["CMD", "curl", "-f", "http://127.0.0.1:8091/health"] interval: 30s timeout: 10s start_period: 60s retries: 3 restart: unless-stopped networks: - breakpilot-network paddleocr-service: build: context: ./paddleocr-service dockerfile: Dockerfile container_name: bp-lehrer-paddleocr profiles: [ocr] platform: linux/amd64 expose: - "8095" environment: PADDLE_PDX_DISABLE_MODEL_SOURCE_CHECK: "True" volumes: - paddleocr_models:/root/.paddlex - paddleocr_models:/root/.paddleocr healthcheck: test: ["CMD", "curl", "-f", "http://127.0.0.1:8095/health"] interval: 30s timeout: 60s start_period: 180s retries: 5 restart: unless-stopped networks: - breakpilot-network breakpilot-drive: build: context: ./breakpilot-drive dockerfile: Dockerfile container_name: bp-lehrer-drive ports: - "3001:3001" environment: API_BASE_URL: http://backend-lehrer:8001 GAME_REQUIRE_AUTH: ${GAME_REQUIRE_AUTH:-false} GAME_ENABLE_LEADERBOARDS: ${GAME_ENABLE_LEADERBOARDS:-true} depends_on: - backend-lehrer healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:3001/health.json"] interval: 30s timeout: 10s retries: 3 profiles: - game restart: unless-stopped networks: - breakpilot-network agent-core: build: context: ./agent-core dockerfile: Dockerfile container_name: bp-lehrer-agent-core profiles: [dev] platform: linux/arm64 environment: BACKEND_URL: http://backend-lehrer:8001 OLLAMA_BASE_URL: ${OLLAMA_BASE_URL:-http://host.docker.internal:11434} extra_hosts: - "host.docker.internal:host-gateway" depends_on: - backend-lehrer restart: unless-stopped networks: - breakpilot-network transcription-worker: build: context: ./backend-lehrer dockerfile: Dockerfile.worker container_name: bp-lehrer-transcription-worker volumes: - transcription_models:/root/.cache/huggingface - transcription_temp:/tmp/transcriptions environment: DATABASE_URL: postgresql://${POSTGRES_USER:-breakpilot}:${POSTGRES_PASSWORD:-breakpilot123}@bp-core-postgres:5432/${POSTGRES_DB:-breakpilot_db} REDIS_URL: redis://bp-core-valkey:6379/0 WHISPER_MODEL: ${WHISPER_MODEL:-base} WHISPER_DEVICE: ${WHISPER_DEVICE:-cpu} WHISPER_COMPUTE_TYPE: ${WHISPER_COMPUTE_TYPE:-int8} PYANNOTE_AUTH_TOKEN: ${PYANNOTE_AUTH_TOKEN:-} MINIO_ENDPOINT: bp-core-minio:9000 MINIO_ACCESS_KEY: ${MINIO_ROOT_USER:-breakpilot} MINIO_SECRET_KEY: ${MINIO_ROOT_PASSWORD:-breakpilot123} MINIO_BUCKET: ${MINIO_BUCKET:-breakpilot-recordings} MINIO_SECURE: "false" TZ: ${TZ:-Europe/Berlin} deploy: resources: limits: memory: 8G reservations: memory: 4G depends_on: core-health-check: condition: service_completed_successfully profiles: - recording restart: unless-stopped networks: - breakpilot-network # ========================================================= # DOCUMENTATION # ========================================================= docs: build: context: . dockerfile: docs-src/Dockerfile container_name: bp-lehrer-docs profiles: [docs] platform: linux/arm64 ports: - "8010:80" healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:80/"] interval: 30s timeout: 10s retries: 3 restart: unless-stopped networks: - breakpilot-network