# Define configurations using YAML anchors x-common-database: &common-database SQLALCHEMY_DATABASE_URL: ${SQLALCHEMY_DATABASE_URL:-postgresql://rhesis-user:rhesis-password@postgres:5432/rhesis-db} SQLALCHEMY_DB_DRIVER: ${SQLALCHEMY_DB_DRIVER:-postgresql} SQLALCHEMY_DB_PORT: ${SQLALCHEMY_DB_PORT:-5432} SQLALCHEMY_DB_USER: ${SQLALCHEMY_DB_USER:-rhesis-user} SQLALCHEMY_DB_PASS: ${SQLALCHEMY_DB_PASS:-rhesis-password} SQLALCHEMY_DB_HOST: ${SQLALCHEMY_DB_HOST:-postgres} SQLALCHEMY_DB_NAME: ${SQLALCHEMY_DB_NAME:-rhesis-db} DB_ENCRYPTION_KEY: ${DB_ENCRYPTION_KEY:-your-32-byte-base64-encryption-key} x-common-redis: &common-redis REDIS_URL: ${REDIS_URL:-redis://:${REDIS_PASSWORD:-rhesis-redis-pass}@redis:6379/0} BROKER_URL: ${BROKER_URL:-redis://:${REDIS_PASSWORD:-rhesis-redis-pass}@redis:6379/0} CELERY_RESULT_BACKEND: ${CELERY_RESULT_BACKEND:-redis://:${REDIS_PASSWORD:-rhesis-redis-pass}@redis:6379/1} # Native authentication configuration (provider-agnostic) x-common-auth: &common-auth # Email/password authentication AUTH_EMAIL_PASSWORD_ENABLED: ${AUTH_EMAIL_PASSWORD_ENABLED:-true} AUTH_REGISTRATION_ENABLED: ${AUTH_REGISTRATION_ENABLED:-true} # Google OAuth (optional - leave empty to disable) GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID:-} GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET:-} # GitHub OAuth (optional - leave empty to disable) GH_CLIENT_ID: ${GH_CLIENT_ID:-} GH_CLIENT_SECRET: ${GH_CLIENT_SECRET:-} # Session secret key (required) SESSION_SECRET_KEY: ${SESSION_SECRET_KEY:-your-session-secret-key-change-in-production} # Legacy Auth0 configuration (for migration period only) x-common-auth0: &common-auth0 AUTH_LEGACY_AUTH0_ENABLED: ${AUTH_LEGACY_AUTH0_ENABLED:-false} AUTH0_DOMAIN: ${AUTH0_DOMAIN:-} AUTH0_AUDIENCE: ${AUTH0_AUDIENCE:-} AUTH0_CLIENT_ID: ${AUTH0_CLIENT_ID:-} AUTH0_CLIENT_SECRET: ${AUTH0_CLIENT_SECRET:-} AUTH0_SECRET_KEY: ${AUTH0_SECRET_KEY:-} x-common-smtp: &common-smtp SMTP_HOST: ${SMTP_HOST:-smtp.example.com} SMTP_PORT: ${SMTP_PORT:-587} SMTP_USER: ${SMTP_USER:-user@example.com} SMTP_PASSWORD: ${SMTP_PASSWORD:-your-smtp-password} FROM_EMAIL: ${FROM_EMAIL:-noreply@example.com} x-common-jwt: &common-jwt JWT_SECRET_KEY: ${JWT_SECRET_KEY:-your-jwt-secret-key-change-in-production} JWT_ALGORITHM: ${JWT_ALGORITHM:-HS256} JWT_ACCESS_TOKEN_EXPIRE_MINUTES: ${JWT_ACCESS_TOKEN_EXPIRE_MINUTES:-10080} x-common-environment: &common-environment ENVIRONMENT: ${ENVIRONMENT:-local} BACKEND_ENV: ${BACKEND_ENV:-local} FRONTEND_ENV: ${FRONTEND_ENV:-local} WORKER_ENV: ${WORKER_ENV:-local} LOG_LEVEL: ${LOG_LEVEL:-DEBUG} x-rhesis-config: &rhesis-config RHESIS_BASE_URL: ${RHESIS_BASE_URL:-https://api.rhesis.ai} RHESIS_API_KEY: ${RHESIS_API_KEY:-your-rhesis-api-key} RHESIS_CONNECTOR_DISABLED: ${RHESIS_CONNECTOR_DISABLED:-true} FRONTEND_URL: ${FRONTEND_URL:-http://localhost:3000} BACKEND_URL: ${BACKEND_URL:-http://backend:8080} DEFAULT_GENERATION_MODEL: ${DEFAULT_GENERATION_MODEL:-rhesis/rhesis-default} DEFAULT_EVALUATION_MODEL: ${DEFAULT_EVALUATION_MODEL:-rhesis/rhesis-default} DEFAULT_EMBEDDING_MODEL: ${DEFAULT_EMBEDDING_MODEL:-vertex_ai/text-embedding-005} x-telemetry-config: &telemetry-config OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-https://telemetry.rhesis.ai} OTEL_SERVICE_NAME: ${OTEL_SERVICE_NAME:-rhesis} OTEL_DEPLOYMENT_TYPE: ${OTEL_DEPLOYMENT_TYPE:-self-hosted} OTEL_RHESIS_TELEMETRY_ENABLED: ${OTEL_RHESIS_TELEMETRY_ENABLED:-true} # Self-hosted: opt-out via env var x-nextjs-frontend: &nextjs-frontend NEXTAUTH_SECRET: ${NEXTAUTH_SECRET:-your-nextauth-secret-change-in-production} NEXTAUTH_URL: ${NEXTAUTH_URL:-http://localhost:3000} NEXT_PUBLIC_API_BASE_URL: ${NEXT_PUBLIC_API_BASE_URL:-http://localhost:8080} NEXT_PUBLIC_QUICK_START: ${NEXT_PUBLIC_QUICK_START:-false} NEXT_TELEMETRY_DISABLED: 1 services: # PostgreSQL Database postgres: image: mirror.gcr.io/pgvector/pgvector:pg16 environment: POSTGRES_DB: ${SQLALCHEMY_DB_NAME:-rhesis-db} POSTGRES_USER: ${SQLALCHEMY_DB_USER:-rhesis-user} POSTGRES_PASSWORD: ${SQLALCHEMY_DB_PASS:-rhesis-password} volumes: - postgres_data:/var/lib/postgresql/data - ./apps/backend/src/rhesis/backend/alembic/create_user.sql:/docker-entrypoint-initdb.d/01-create-user.sql ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U ${SQLALCHEMY_DB_USER:-rhesis-user} -d ${SQLALCHEMY_DB_NAME:-rhesis-db}"] interval: 10s timeout: 5s retries: 5 networks: - rhesis-network # Redis for Celery redis: image: mirror.gcr.io/redis:7-alpine command: redis-server --requirepass ${REDIS_PASSWORD:-rhesis-redis-pass} ports: - "6379:6379" volumes: - redis_data:/data environment: - REDIS_PASSWORD=${REDIS_PASSWORD:-rhesis-redis-pass} healthcheck: test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-rhesis-redis-pass}", "ping"] interval: 10s timeout: 5s retries: 5 networks: - rhesis-network # Backend API backend: build: context: . dockerfile: apps/backend/Dockerfile target: backend environment: <<: [*common-database, *common-redis, *common-auth, *common-auth0, *common-smtp, *common-jwt, *common-environment, *rhesis-config, *telemetry-config] LOG_LEVEL: ${LOG_LEVEL:-DEBUG} QUICK_START: ${QUICK_START:-false} ports: - "8080:8080" extra_hosts: - "host.docker.internal:host-gateway" depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - rhesis-network restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 start_period: 60s # Celery Worker worker: build: context: . dockerfile: apps/backend/Dockerfile target: worker environment: <<: [*common-database, *common-redis, *common-auth, *common-auth0, *common-smtp, *common-jwt, *common-environment, *rhesis-config] LOG_LEVEL: ${CELERY_WORKER_LOGLEVEL:-INFO} CELERY_WORKER_CONCURRENCY: ${CELERY_WORKER_CONCURRENCY:-8} CELERY_WORKER_PREFETCH_MULTIPLIER: ${CELERY_WORKER_PREFETCH_MULTIPLIER:-4} CELERY_WORKER_LOGLEVEL: ${CELERY_WORKER_LOGLEVEL:-INFO} USE_TCP_DATABASE: ${USE_TCP_DATABASE:-true} ENABLE_FLOWER: ${ENABLE_FLOWER:-no} ports: - "8081:8081" extra_hosts: - "host.docker.internal:host-gateway" depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - rhesis-network restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8081/health/basic"] interval: 30s timeout: 10s retries: 3 start_period: 60s # Frontend frontend: build: context: ./apps/frontend dockerfile: Dockerfile args: FRONTEND_ENV: ${FRONTEND_ENV:-local} NEXT_PUBLIC_API_BASE_URL: ${NEXT_PUBLIC_API_BASE_URL:-http://localhost:8080} NEXT_PUBLIC_QUICK_START: ${NEXT_PUBLIC_QUICK_START:-false} environment: <<: [*nextjs-frontend, *common-environment, *rhesis-config] PORT: ${FRONTEND_PORT:-3000} ports: - "3000:3000" depends_on: backend: condition: service_healthy networks: - rhesis-network restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/api/auth/session"] interval: 30s timeout: 10s retries: 3 start_period: 60s # Documentation docs: build: context: ./docs dockerfile: src/Dockerfile args: ROBOTS_NOINDEX: ${ROBOTS_NOINDEX:-false} environment: <<: [*common-environment] PORT: 3001 ROBOTS_NOINDEX: ${ROBOTS_NOINDEX:-false} ports: - "3001:3001" networks: - rhesis-network restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3001/"] interval: 30s timeout: 10s retries: 3 start_period: 60s volumes: postgres_data: driver: local redis_data: driver: local networks: rhesis-network: driver: bridge