# SPDX-FileCopyrightText: 2026 Apoorv Garg # SPDX-FileCopyrightText: 2026 Subramania Raja # SPDX-FileCopyrightText: 2026 Hari Srinivasan # SPDX-FileCopyrightText: 2026 Kaushik Kumar # SPDX-FileCopyrightText: 2026 Lokesh Selvam # SPDX-FileCopyrightText: 2026 Shaan Narendran # SPDX-FileCopyrightText: 2026 Shreem Seth # SPDX-FileCopyrightText: 2026 Swathi Saravanan # SPDX-FileCopyrightText: 2026 Yash Gadgil # SPDX-License-Identifier: Apache-2.0 services: observal-init: build: context: .. dockerfile: docker/Dockerfile.api image: ghcr.io/agenticresourceregistry/observal-api:latest command: ["/app/entrypoint.sh"] env_file: - ../.env environment: - JWT_KEY_DIR=/data/keys depends_on: observal-db: condition: service_healthy observal-clickhouse: condition: service_healthy observal-redis: condition: service_healthy restart: "no" read_only: true tmpfs: - /tmp security_opt: - no-new-privileges:true networks: - observal-net observal-api: build: context: .. dockerfile: docker/Dockerfile.api image: ghcr.io/agenticresourceregistry/observal-api:latest command: [ "/app/.venv/bin/python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "${API_WORKERS:-2}", ] env_file: - ../.env environment: - JWT_KEY_DIR=/data/keys - MIGRATION_ARTIFACT_ROOT=/data/migration_artifacts - SKIP_DDL_ON_STARTUP=true - DEMO_SUPER_ADMIN_EMAIL=${DEMO_SUPER_ADMIN_EMAIL:-super@demo.example} - DEMO_SUPER_ADMIN_PASSWORD=${DEMO_SUPER_ADMIN_PASSWORD:-super-changeme} - DEMO_ADMIN_EMAIL=${DEMO_ADMIN_EMAIL:-admin@demo.example} - DEMO_ADMIN_PASSWORD=${DEMO_ADMIN_PASSWORD:-admin-changeme} - DEMO_REVIEWER_EMAIL=${DEMO_REVIEWER_EMAIL:-reviewer@demo.example} - DEMO_REVIEWER_PASSWORD=${DEMO_REVIEWER_PASSWORD:-reviewer-changeme} - DEMO_USER_EMAIL=${DEMO_USER_EMAIL:-user@demo.example} - DEMO_USER_PASSWORD=${DEMO_USER_PASSWORD:-user-changeme} volumes: - apidata:/data - ~/.observal/logs:/home/appuser/.observal/logs depends_on: observal-init: condition: service_completed_successfully observal-redis: condition: service_healthy restart: unless-stopped healthcheck: test: [ "CMD-SHELL", 'python -c "import urllib.request; urllib.request.urlopen(''http://localhost:8000/readyz'')"', ] interval: 10s timeout: 5s retries: 5 start_period: 60s start_interval: 1s read_only: true tmpfs: - /tmp security_opt: - no-new-privileges:true deploy: replicas: ${API_REPLICAS:-1} resources: limits: memory: ${API_MEMORY_LIMIT:-1536M} networks: - observal-net observal-db: restart: unless-stopped image: postgres:18 ports: - "127.0.0.1:${POSTGRES_HOST_PORT:-5432}:5432" env_file: - ../.env environment: POSTGRES_DB: observal command: > postgres -c max_connections=300 -c shared_buffers=128MB -c work_mem=8MB -c effective_cache_size=384MB -c maintenance_work_mem=64MB -c random_page_cost=1.1 volumes: - pgdata:/var/lib/postgresql healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 3s retries: 5 deploy: resources: limits: memory: 512M networks: - observal-net observal-clickhouse: restart: unless-stopped image: clickhouse/clickhouse-server:26.6 ports: - "127.0.0.1:${CLICKHOUSE_HOST_PORT:-8123}:8123" env_file: - ../.env environment: CLICKHOUSE_DB: observal MAX_SERVER_MEMORY_USAGE_RATIO: "0.8" volumes: - chdata:/var/lib/clickhouse - ./clickhouse/config.d:/etc/clickhouse-server/config.d:ro - ./clickhouse/users.d:/etc/clickhouse-server/users.d healthcheck: test: [ "CMD-SHELL", "clickhouse-client --password ${CLICKHOUSE_PASSWORD:-clickhouse} --query 'SELECT 1'", ] interval: 5s timeout: 3s retries: 10 deploy: resources: limits: memory: ${CLICKHOUSE_MEMORY_LIMIT:-2G} networks: - observal-net observal-redis: restart: unless-stopped image: redis:8-alpine ports: - "127.0.0.1:${REDIS_HOST_PORT:-6379}:6379" command: redis-server --maxmemory 200mb --maxmemory-policy volatile-lru volumes: - redisdata:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 deploy: resources: limits: memory: 256M networks: - observal-net observal-worker: build: context: .. dockerfile: docker/Dockerfile.api image: ghcr.io/agenticresourceregistry/observal-api:latest command: [ "/app/.venv/bin/python", "-c", "import asyncio; asyncio.set_event_loop(asyncio.new_event_loop()); from arq import run_worker; from worker import WorkerSettings; run_worker(WorkerSettings)", ] env_file: - ../.env environment: - MIGRATION_ARTIFACT_ROOT=/data/migration_artifacts volumes: - apidata:/data depends_on: observal-init: condition: service_completed_successfully observal-redis: condition: service_healthy restart: unless-stopped read_only: true tmpfs: - /tmp security_opt: - no-new-privileges:true deploy: replicas: ${WORKER_REPLICAS:-1} resources: limits: memory: ${WORKER_MEMORY_LIMIT:-1536M} networks: - observal-net observal-web: build: context: .. dockerfile: docker/Dockerfile.web image: ghcr.io/agenticresourceregistry/observal-web:latest ports: - "${WEB_HOST_PORT:-3000}:3000" depends_on: observal-lb: condition: service_started restart: unless-stopped read_only: true tmpfs: - /var/cache/nginx - /var/log/nginx - /var/run - /tmp security_opt: - no-new-privileges:true healthcheck: test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:3000/"] interval: 5s timeout: 3s retries: 3 deploy: resources: limits: memory: 32M networks: - observal-net observal-lb: image: nginx:1.31-alpine ports: - "${LB_HOST_PORT:-80}:80" volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro depends_on: observal-api: condition: service_healthy restart: unless-stopped deploy: resources: limits: memory: 64M networks: - observal-net volumes: pgdata: chdata: redisdata: apidata: networks: observal-net: driver: bridge