version: '3.8' services: # MongoDB Database mongodb: image: mongo:7.0 container_name: tractatus-mongodb restart: unless-stopped ports: - "${MONGODB_PORT:-27017}:27017" environment: MONGO_INITDB_ROOT_USERNAME: ${MONGODB_USERNAME:-tractatus} MONGO_INITDB_ROOT_PASSWORD: ${MONGODB_PASSWORD:-changeme} MONGO_INITDB_DATABASE: ${MONGODB_DATABASE:-tractatus_prod} volumes: - mongodb_data:/data/db - mongodb_config:/data/configdb networks: - tractatus-network healthcheck: test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test --quiet interval: 10s timeout: 5s retries: 5 # Tractatus Application tractatus-app: build: context: .. dockerfile: deployment-quickstart/Dockerfile container_name: tractatus-app restart: unless-stopped ports: - "${APP_PORT:-9000}:9000" environment: NODE_ENV: ${NODE_ENV:-production} PORT: 9000 MONGODB_URI: mongodb://${MONGODB_USERNAME:-tractatus}:${MONGODB_PASSWORD:-changeme}@mongodb:27017/${MONGODB_DATABASE:-tractatus_prod}?authSource=admin JWT_SECRET: ${JWT_SECRET} ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY} ADMIN_EMAIL: ${ADMIN_EMAIL:-admin@tractatus.local} ADMIN_PASSWORD: ${ADMIN_PASSWORD} SESSION_SECRET: ${SESSION_SECRET} BASE_URL: ${BASE_URL:-http://localhost:9000} # Governance Service Configuration BOUNDARY_ENFORCER_ENABLED: ${BOUNDARY_ENFORCER_ENABLED:-true} CONTEXT_PRESSURE_ENABLED: ${CONTEXT_PRESSURE_ENABLED:-true} CROSS_REF_VALIDATOR_ENABLED: ${CROSS_REF_VALIDATOR_ENABLED:-true} PERSISTENCE_CLASSIFIER_ENABLED: ${PERSISTENCE_CLASSIFIER_ENABLED:-true} METACOGNITIVE_VERIFIER_ENABLED: ${METACOGNITIVE_VERIFIER_ENABLED:-true} # Performance & Limits RATE_LIMIT_WINDOW_MS: ${RATE_LIMIT_WINDOW_MS:-900000} RATE_LIMIT_MAX_REQUESTS: ${RATE_LIMIT_MAX_REQUESTS:-100} MAX_FILE_SIZE: ${MAX_FILE_SIZE:-10485760} # Feature Flags BLOG_ENABLED: ${BLOG_ENABLED:-true} KOHA_ENABLED: ${KOHA_ENABLED:-true} DEMOS_ENABLED: ${DEMOS_ENABLED:-true} ANALYTICS_ENABLED: ${ANALYTICS_ENABLED:-false} volumes: - app_logs:/app/logs - app_uploads:/app/uploads depends_on: mongodb: condition: service_healthy networks: - tractatus-network healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:9000/api/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s # Umami Analytics (Privacy-Preserving) umami: image: ghcr.io/umami-software/umami:postgresql-latest container_name: tractatus-umami restart: unless-stopped ports: - "${UMAMI_PORT:-3000}:3000" environment: DATABASE_URL: postgresql://${UMAMI_DB_USER:-umami}:${UMAMI_DB_PASSWORD:-changeme}@umami-db:5432/${UMAMI_DB_NAME:-umami} DATABASE_TYPE: postgresql APP_SECRET: ${UMAMI_APP_SECRET} TRACKER_SCRIPT_NAME: ${UMAMI_TRACKER_SCRIPT:-umami} DISABLE_TELEMETRY: ${UMAMI_DISABLE_TELEMETRY:-1} depends_on: umami-db: condition: service_healthy networks: - tractatus-network healthcheck: test: ['CMD-SHELL', 'curl -f http://localhost:3000/api/heartbeat || exit 1'] interval: 10s timeout: 5s retries: 5 # PostgreSQL for Umami umami-db: image: postgres:15-alpine container_name: tractatus-umami-db restart: unless-stopped environment: POSTGRES_DB: ${UMAMI_DB_NAME:-umami} POSTGRES_USER: ${UMAMI_DB_USER:-umami} POSTGRES_PASSWORD: ${UMAMI_DB_PASSWORD:-changeme} volumes: - umami_db_data:/var/lib/postgresql/data networks: - tractatus-network healthcheck: test: ['CMD-SHELL', 'pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}'] interval: 5s timeout: 5s retries: 5 volumes: mongodb_data: driver: local mongodb_config: driver: local app_logs: driver: local app_uploads: driver: local umami_db_data: driver: local networks: tractatus-network: driver: bridge # Optional: Nginx reverse proxy (uncomment if needed) # nginx: # image: nginx:alpine # container_name: tractatus-nginx # restart: unless-stopped # ports: # - "80:80" # - "443:443" # volumes: # - ./nginx.conf:/etc/nginx/nginx.conf:ro # - ./ssl:/etc/nginx/ssl:ro # depends_on: # - tractatus-app # networks: # - tractatus-network