Files
ss-tools/docker-compose.enterprise-clean.yml
busya 12118ac4ec fix(security): resolve Critical+High findings from module audit — agent, translate, superset_client
P0 — CRITICAL (CWE-798): JWT_SECRET crash-early
  Replace hardcoded super-secret-key fallback with os.environ["JWT_SECRET"]
  and ${JWT_SECRET:?} syntax in app.py + docker-compose files

P1 — HIGH: Frontend dependency CVEs
  Upgrade svelte 5.43.8 → 5.56.4 — resolves devalue DoS (GHSA-g2pg-6438-jwpf)
  and svelte XSS (GHSA-crpf-4hrx-3jrp, GHSA-m56q-vw4c-c2cp, GHSA-rcqx-6q8c-2c42)

P2 — MEDIUM: Logging hygiene + contract gaps + tool resolver refactor
  Apply _redact_sensitive_fields() in middleware + event streaming
  Truncate LLM error body to 100 chars
  Add @RATIONALE/@REJECTED to HandleResume + SaveConversation
  Refactor deterministic intent matching → LLM-driven tool resolution

P3 — LOW: Translate logging hardening
  Move _sanitize_url() to _utils.py (shared, no circular imports)
  Sanitize base_url before logging in _llm_call.py and _llm_async_http.py
  Emit EXPLORE warning when LLM_SSL_VERIFY=false disables TLS

superset_client module: passed clean — no changes needed
2026-07-01 13:17:29 +03:00

110 lines
7.8 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# #region docker.compose.enterprise-clean [C:4] [TYPE Module] [SEMANTICS docker,compose,enterprise]
# @BRIEF Enterprise docker compose — сборка backend + frontend + agent из исходников, внешний Postgres, корп. сертификаты.
# @PRE Docker и docker compose установлены. Файлы .env.enterprise-clean настроены.
# Postgres: внешний, доступный по POSTGRES_HOST:POSTGRES_PORT.
# Сертификаты: опциональные .crt файлы в CERTS_PATH монтируются в /opt/certs.
# @POST Сервисы backend, frontend и agent запущены. SSL терминация в nginx опциональна.
# @SIDE_EFFECT backend использует ENTRYPOINT для установки сертификатов и bootstrap admin.
# frontend автоопределяет наличие SSL сертификатов и переключает nginx конфиг.
# agent запускает Gradio-сервер с LangGraph на порту 7860.
# @LAYER Infrastructure
# @RELATION DEPENDS_ON -> [docker/backend.Dockerfile]
# @RELATION DEPENDS_ON -> [docker/frontend.Dockerfile]
# @RELATION DEPENDS_ON -> [docker/Dockerfile.agent]
# @RELATION DEPENDS_ON -> [docker/nginx.conf]
# @RELATION DEPENDS_ON -> [docker/nginx.ssl.conf]
# @RELATION DEPENDS_ON -> [docker/frontend.entrypoint.sh]
# @RELATION DEPENDS_ON -> [docker/backend.entrypoint.sh]
# @DATA_CONTRACT Input: .env.enterprise-clean + ./certs/*.crt -> Output: запущенные контейнеры
# @INVARIANT Внешний Postgres НЕ требует healthcheck внутри compose — ответственность оператора.
# Backend entrypoint использует wait_for_db() (retry до 30 раз) для проверки доступности БД
# перед запуском миграций. Если БД недоступна — контейнер exit(1) после таймаута.
# @RATIONALE Нет depends_on для backend → внешний PostgreSQL: оператор гарантирует доступность.
# wait_for_db() в entrypoint.sh обеспечивает graceful retry вместо мгновенного crash.
# @INVARIANT Если CERTS_PATH пуст или не содержит .crt файлов, entrypoint не падает.
# @INVARIANT nginx слушает порт 80 всегда. Порт 443 включается только если есть server.crt + server.key.
# @RATIONALE Отказ от встроенного postgres-container: корпоративный стандарт — внешний PostgreSQL
# с TLS, бэкапами и мониторингом на уровне инфраструктуры.
# @RATIONALE Build из исходников вместо pre-built images: предприятие контролирует версии кода
# и может патчить зависимости. Не подходит для air-gapped — для этого есть bundle:light.
# @REJECTED Использование `image:` + `pull_policy: never` отвергнуто — не работает для сборки
# из исходников на целевой машине. Гибридный `build: + image:` тоже отвергнут — усложняет
# логику build.sh и сбивает с толку оператора.
services:
backend:
build:
context: .
dockerfile: docker/backend.Dockerfile
restart: unless-stopped
environment:
DATABASE_URL: postgresql+psycopg2://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env.enterprise-clean}@${POSTGRES_HOST:?Set POSTGRES_HOST in .env.enterprise-clean}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-ss_tools}
TASKS_DATABASE_URL: postgresql+psycopg2://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env.enterprise-clean}@${POSTGRES_HOST:?Set POSTGRES_HOST in .env.enterprise-clean}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-ss_tools}
AUTH_DATABASE_URL: postgresql+psycopg2://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env.enterprise-clean}@${POSTGRES_HOST:?Set POSTGRES_HOST in .env.enterprise-clean}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-ss_tools}
BACKEND_PORT: 8000
ENABLE_BELIEF_STATE_LOGGING: ${ENABLE_BELIEF_STATE_LOGGING:-true}
TASK_LOG_LEVEL: ${TASK_LOG_LEVEL:-INFO}
INITIAL_ADMIN_CREATE: ${INITIAL_ADMIN_CREATE:-false}
INITIAL_ADMIN_USERNAME: ${INITIAL_ADMIN_USERNAME:-admin}
INITIAL_ADMIN_PASSWORD: ${INITIAL_ADMIN_PASSWORD:-}
INITIAL_ADMIN_EMAIL: ${INITIAL_ADMIN_EMAIL:-}
# Обязательно: задайте ENCRYPTION_KEY в .env.enterprise-clean
# Сгенерируйте: python3 -c "import base64,os; print(base64.urlsafe_b64encode(os.urandom(32)).decode())"
ENCRYPTION_KEY: ${ENCRYPTION_KEY:?ENCRYPTION_KEY обязателен — сгенерируйте и укажите в .env.enterprise-clean}
OPENAI_API_KEY: ${OPENAI_API_KEY:-}
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
FEATURES__DATASET_REVIEW: ${FEATURES__DATASET_REVIEW:-true}
FEATURES__HEALTH_MONITOR: ${FEATURES__HEALTH_MONITOR:-true}
# Путь до сертификатов внутри контейнера — всегда /opt/certs
CERTS_PATH: /opt/certs
# URL CA-сертификатов для LLM-провайдеров (скачка на старте, DER→PEM конвертация)
LLM_CA_CERT_URLS: ${LLM_CA_CERT_URLS:-}
# Отключить SSL verify для LLM (когда корп. сертификаты не установлены в контейнере)
LLM_SSL_VERIFY: ${LLM_SSL_VERIFY:-true}
ports:
- "${BACKEND_HOST_PORT:-8001}:8000"
volumes:
# Единая точка хранения: бэкапы → /app/storage/backups/, git-repos → /app/storage/repositories/, LLM-скриншоты → /app/storage/screenshots/
- ./storage:/app/storage
# Корпоративные CA-сертификаты (.crt файлы). Монтируются в /opt/certs,
# entrypoint.sh установит их в системное хранилище доверия.
- ${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"
# Если в CERTS_PATH есть server.crt + server.key — nginx включит HTTPS на 443.
# Если cert-файлов нет — порт 443 не открывается, entrypoint использует HTTP-only конфиг.
- "${FRONTEND_SSL_PORT:-443}:443"
volumes:
# Для frontend тоже можно смонтировать сертификаты — nginx entrypoint
# автоматически установит CA-сертификаты в Alpine и переключит SSL конфиг.
- ${CERTS_PATH:-./certs}:/opt/certs:ro
agent:
build:
context: .
dockerfile: docker/Dockerfile.agent
restart: unless-stopped
depends_on:
- backend
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
JWT_SECRET: ${JWT_SECRET:?JWT_SECRET must be set — crash-early, no default fallback}
SERVICE_JWT: ${SERVICE_JWT:-agent-service-secret}
DATABASE_URL: postgresql+psycopg2://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env.enterprise-clean}@${POSTGRES_HOST:?Set POSTGRES_HOST in .env.enterprise-clean}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-ss_tools}
GRADIO_SERVER_PORT: 7860
ports:
- "${AGENT_HOST_PORT:-7860}:7860"
# #endregion docker.compose.enterprise-clean