x-app-env: &app-env OMNARA_DATABASE_URL: postgres://omnara:omnara@postgres:5432/omnara?sslmode=disable OMNARA_REDIS_URL: redis://redis:6379/0 OMNARA_PUBLIC_URL: ${OMNARA_PUBLIC_URL:-http://localhost:8000} OMNARA_LOG_LEVEL: ${OMNARA_LOG_LEVEL:-info} OMNARA_ALLOW_INSECURE_DEV_DEFAULTS: ${OMNARA_ALLOW_INSECURE_DEV_DEFAULTS:-1} OMNARA_SECRET_ENCRYPTION_KEYS: ${OMNARA_SECRET_ENCRYPTION_KEYS:-} OMNARA_SECRET_ENCRYPTION_ACTIVE_KEY_ID: ${OMNARA_SECRET_ENCRYPTION_ACTIVE_KEY_ID:-} OMNARA_SKILL_DOWNLOAD_SIGNING_KEY: ${OMNARA_SKILL_DOWNLOAD_SIGNING_KEY:-} x-blob-env: &blob-env OMNARA_BLOB_S3_BUCKET: ${OMNARA_BLOB_S3_BUCKET:-omnara} OMNARA_BLOB_S3_REGION: ${OMNARA_BLOB_S3_REGION:-us-east-1} OMNARA_BLOB_S3_ENDPOINT: ${OMNARA_BLOB_S3_ENDPOINT:-http://minio:9000} OMNARA_BLOB_S3_ACCESS_KEY_ID: ${OMNARA_BLOB_S3_ACCESS_KEY_ID:-omnara} OMNARA_BLOB_S3_SECRET_ACCESS_KEY: ${OMNARA_BLOB_S3_SECRET_ACCESS_KEY:-omnara-blobs} OMNARA_BLOB_S3_USE_PATH_STYLE: ${OMNARA_BLOB_S3_USE_PATH_STYLE:-1} services: redis: image: valkey/valkey:9-alpine ports: - "${REDIS_HOST_PORT:-6379}:6379" healthcheck: test: ["CMD", "valkey-cli", "ping"] interval: 2s timeout: 2s retries: 20 postgres: image: postgres:18-alpine environment: POSTGRES_USER: omnara POSTGRES_PASSWORD: omnara POSTGRES_DB: omnara ports: - "${POSTGRES_HOST_PORT:-55432}:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U omnara -d omnara"] interval: 2s timeout: 2s retries: 20 volumes: - postgres18-data:/var/lib/postgresql minio: image: quay.io/minio/minio:RELEASE.2025-04-22T22-12-26Z command: server /data environment: MINIO_ROOT_USER: omnara MINIO_ROOT_PASSWORD: omnara-blobs ports: - "59000:9000" healthcheck: test: ["CMD", "curl", "-f", "http://127.0.0.1:9000/minio/health/live"] interval: 2s timeout: 2s retries: 20 volumes: - minio-data:/data # One-shot bucket provisioning: the application assumes buckets exist. minio-init: image: quay.io/minio/mc:RELEASE.2025-04-16T18-13-26Z depends_on: minio: condition: service_healthy entrypoint: > /bin/sh -c " mc alias set local http://minio:9000 omnara omnara-blobs && mc mb --ignore-existing local/omnara local/omnara-test " restart: "no" # One-shot schema migration: app services depend on its successful exit and # never apply migrations themselves. migrate: profiles: ["app"] image: ghcr.io/omnara-ai/omnara-migrations:${OMNARA_RELEASE:-latest} environment: OMNARA_DATABASE_URL: postgres://omnara:omnara@postgres:5432/omnara?sslmode=disable OMNARA_MIGRATION_TIMEOUT: ${OMNARA_MIGRATION_TIMEOUT:-30m} depends_on: postgres: condition: service_healthy restart: "no" api: profiles: ["app"] image: ghcr.io/omnara-ai/omnara-api:${OMNARA_RELEASE:-latest} environment: <<: [*app-env, *blob-env] OMNARA_EMAIL_DRIVER: ${OMNARA_EMAIL_DRIVER:-console} OMNARA_EMAIL_FROM: ${OMNARA_EMAIL_FROM:-} OMNARA_SMTP_ADDR: ${OMNARA_SMTP_ADDR:-} OMNARA_SMTP_USERNAME: ${OMNARA_SMTP_USERNAME:-} OMNARA_SMTP_PASSWORD: ${OMNARA_SMTP_PASSWORD:-} OMNARA_SMTP_REQUIRE_TLS: ${OMNARA_SMTP_REQUIRE_TLS:-} SENDGRID_API_KEY: ${SENDGRID_API_KEY:-} OMNARA_AUTH_SIGNUP_ENABLED: ${OMNARA_AUTH_SIGNUP_ENABLED:-1} OMNARA_AUTH_PASSWORD_RESET_ENABLED: ${OMNARA_AUTH_PASSWORD_RESET_ENABLED:-1} OMNARA_AUTH_CONNECTORS_JSON: ${OMNARA_AUTH_CONNECTORS_JSON:-} OMNARA_TRUSTED_PROXY_CIDRS: ${OMNARA_TRUSTED_PROXY_CIDRS:-} OMNARA_BILLING_URL: ${OMNARA_BILLING_URL:-} OMNARA_DAEMON_RELEASE_URL: ${OMNARA_DAEMON_RELEASE_URL:-https://github.com/omnara-ai/omnara/releases/download/omnarad-stable} depends_on: migrate: condition: service_completed_successfully redis: condition: service_healthy minio-init: condition: service_completed_successfully restart: unless-stopped worker: profiles: ["app"] image: ghcr.io/omnara-ai/omnara-worker:${OMNARA_RELEASE:-latest} environment: <<: [*app-env, *blob-env] OMNARA_WORKER_CAPACITY: ${OMNARA_WORKER_CAPACITY:-4} OMNARA_WORKER_ASYNC_TOOL_CAPACITY: ${OMNARA_WORKER_ASYNC_TOOL_CAPACITY:-32} OMNARA_WORKER_BACKGROUND_TOOL_CAPACITY: ${OMNARA_WORKER_BACKGROUND_TOOL_CAPACITY:-8} EXA_API_KEY: ${EXA_API_KEY:-} depends_on: migrate: condition: service_completed_successfully redis: condition: service_healthy minio-init: condition: service_completed_successfully restart: unless-stopped maintenance: profiles: ["app"] image: ghcr.io/omnara-ai/omnara-maintenance:${OMNARA_RELEASE:-latest} environment: <<: *app-env OMNARA_MAINTENANCE_INTERVAL: ${OMNARA_MAINTENANCE_INTERVAL:-1s} depends_on: migrate: condition: service_completed_successfully redis: condition: service_healthy restart: unless-stopped web: profiles: ["app"] image: ghcr.io/omnara-ai/omnara-web:${OMNARA_RELEASE:-latest} restart: unless-stopped gateway: profiles: ["app"] image: nginxinc/nginx-unprivileged:1.29.5-alpine ports: - "${GATEWAY_HOST_PORT:-8000}:8080" volumes: - ./gateway.nginx.conf:/etc/nginx/conf.d/default.conf:ro depends_on: api: condition: service_started web: condition: service_started restart: unless-stopped volumes: postgres18-data: minio-data: networks: default: name: omnara-control-plane