Files
ss-tools/docker-compose.yml
busya 58d06fb287 fix(ssl+agent): capath for all HTTP clients + isolate gradio import
SSL fix (ADR-0009 Finding 7):
- Replace ssl.create_default_context() with system_ssl_context(capath)
  in client_registry.py, async_network.py, notifications/providers.py,
  git/_base.py. Previous fix (0.5.1) only covered LLM clients; the
  Superset API client still used ssl.create_default_context() which
  loads cafile (flat bundle) where OpenSSL 3.x ignores intermediate CA
  certificates. system_ssl_context() uses capath only (hash symlinks).

Agent fix:
- Extract _check_llm_provider_health + _llm_status from agent/app.py
  into agent/_llm_health.py. The /api/agent/llm-status endpoint was
  importing from agent/app.py which triggers 'import gradio' at module
  level. Backend container does not have gradio installed, causing
  ModuleNotFoundError (500 error) every 30s on health check polling.

Config:
- Add ALLOWED_ORIGINS to docker-compose.yml + docker-compose.enterprise-clean.yml

ADR-0009 updated: Layer 2 table expanded with 4 missing clients,
Finding 5 reconciled (LLM_CA_CERT_URLS restored in 0.5.1), version 0.5.2.

Verified: 1110 unit tests passed, gradio import isolation confirmed.
2026-07-07 12:18:43 +03:00

85 lines
2.5 KiB
YAML

services:
db:
image: ${POSTGRES_IMAGE:-postgres:16-alpine}
restart: unless-stopped
environment:
POSTGRES_DB: ss_tools
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- "${POSTGRES_HOST_PORT:-5432}:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d ss_tools"]
interval: 10s
timeout: 5s
retries: 10
backend:
build:
context: .
dockerfile: docker/backend.Dockerfile
restart: unless-stopped
env_file:
- ./backend/.env
depends_on:
db:
condition: service_healthy
environment:
POSTGRES_URL: postgresql+psycopg2://postgres:postgres@db:5432/ss_tools
DATABASE_URL: postgresql+psycopg2://postgres:postgres@db:5432/ss_tools
TASKS_DATABASE_URL: postgresql+psycopg2://postgres:postgres@db:5432/ss_tools
AUTH_DATABASE_URL: postgresql+psycopg2://postgres:postgres@db:5432/ss_tools
BACKEND_PORT: 8000
ALLOWED_ORIGINS: ${ALLOWED_ORIGINS:-}
INITIAL_ADMIN_CREATE: ${INITIAL_ADMIN_CREATE:-false}
INITIAL_ADMIN_USERNAME: ${INITIAL_ADMIN_USERNAME:-admin}
INITIAL_ADMIN_PASSWORD: ${INITIAL_ADMIN_PASSWORD:-}
FEATURES__DATASET_REVIEW: ${FEATURES__DATASET_REVIEW:-true}
FEATURES__HEALTH_MONITOR: ${FEATURES__HEALTH_MONITOR:-true}
LLM_CA_CERT_URLS: ${LLM_CA_CERT_URLS:-}
ports:
- "${BACKEND_HOST_PORT:-8001}:8000"
volumes:
- ./storage:/app/storage
- ${CERTS_PATH:-./certs}:/opt/certs:ro
agent:
build:
context: .
dockerfile: docker/Dockerfile.agent
restart: unless-stopped
depends_on:
db:
condition: service_healthy
backend:
condition: service_started
environment:
LLM_API_KEY: ${LLM_API_KEY:-}
LLM_BASE_URL: ${LLM_BASE_URL:-https://api.openai.com/v1}
LLM_MODEL: ${LLM_MODEL:-gpt-4o}
FASTAPI_URL: http://backend:8000
AUTH_SECRET_KEY: ${AUTH_SECRET_KEY:?Set AUTH_SECRET_KEY in .env}
SERVICE_JWT: ${SERVICE_JWT:-agent-service-secret}
DATABASE_URL: postgresql+psycopg2://postgres:postgres@db:5432/ss_tools
GRADIO_SERVER_PORT: 7860
LLM_CA_CERT_URLS: ${LLM_CA_CERT_URLS:-}
ports:
- "7860" # internal only, proxied through nginx
volumes:
- ${CERTS_PATH:-./certs}:/opt/certs:ro
frontend:
build:
context: .
dockerfile: docker/frontend.Dockerfile
restart: unless-stopped
depends_on:
- backend
ports:
- "${FRONTEND_HOST_PORT:-8000}:80"
volumes:
postgres_data: