Centralized SSL via one contract: CERTS_PATH=/opt/certs mounted into all containers.
Backend:
- NEW: backend/src/core/ssl.py — system_ssl_context(), httpx_verify(),
cert_dir_inventory()
- LLMClient._get_ssl_verify() → delegates to core.ssl
- _llm_async_http._get_verify() → delegates to core.ssl
- Removed LLM_SSL_VERIFY env reading from all runtime code
Docker:
- NEW: docker/certs.sh — shared cert installer (PEM/DER/cer to .crt conversion,
update-ca-certificates, hash symlinks, NSS import)
- NEW: docker/agent.entrypoint.sh — agent entrypoint with cert installation
- backend.entrypoint.sh → uses certs.sh instead of install_llm_ca_certs
- Dockerfile.agent → adds ca-certificates, openssl, entrypoint
Compose:
- Removed LLM_CA_CERT_URLS and LLM_SSL_VERIFY from all compose files
- Added CERTS_PATH volume mount to agent (dev + enterprise)
- Added certs volume mount to backend/agent in dev compose
Env examples:
- Removed LLM_SSL_VERIFY, LLM_CA_CERT_URLS from .env.example,
.env.enterprise-clean.example, .env.current.example, .env.master.example,
backend/.env.example
- Enhanced CERTS_PATH comments with accepted formats
Diagnostics:
- diag_container.py: removed LLM_* checks, added CERTS_PATH inventory,
uses core.ssl for context creation
Tests:
- Updated test_llm_analysis_service, test_llm_async_http,
test_client_headers to verify centralized ssl context (no env disable)
- 4/4 SSL tests pass
62 lines
3.5 KiB
Docker
62 lines
3.5 KiB
Docker
# #region docker.agent.Dockerfile [C:3] [TYPE Module] [SEMANTICS docker,agent,build]
|
||
# @BRIEF Agent Dockerfile — Python 3.11 slim + Gradio + LangGraph agent.
|
||
# @LAYER Infrastructure
|
||
# @RELATION DEPENDS_ON -> [EXT:path:backend/requirements.txt]
|
||
# @PRE Docker builder context — корень проекта. backend/ и docker/ доступны.
|
||
# @POST Образ с Gradio-агентом, LangGraph, минимальной копией backend/src/.
|
||
# @RATIONALE Агенту нужен только src.agent.* и src.core.cot_logger (чистый stdlib).
|
||
# Полный трассировщик импортов показал:
|
||
# src.agent.app → src.agent.{context,document_parser,langgraph_setup,middleware,tools}
|
||
# → src.core.cot_logger (stdlib-only, нет бизнес-логики)
|
||
# Ни src.models, ни src.api, ни src.services, ни src.plugins НЕ импортируются.
|
||
# @REJECTED COPY backend/ /app/backend/ rejected — нарушает принцип изоляции контейнеров.
|
||
# COPY только backend/src/agent/ недостаточно — нужен src.core.cot_logger.
|
||
|
||
FROM python:3.11-slim
|
||
|
||
WORKDIR /app
|
||
|
||
# Install system deps for pdfplumber + psycopg (v3 needs libpq) + certs
|
||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||
libgl1 libglib2.0-0 libpq5 ca-certificates openssl && rm -rf /var/lib/apt/lists/*
|
||
|
||
# Python dependencies — agent runtime (gradio, langgraph, httpx, pdfplumber, ...)
|
||
# Без sentence-transformers — embedding router безопасно отключается при ImportError.
|
||
ARG WITH_EMBEDDINGS=false
|
||
|
||
COPY backend/requirements-agent.txt /app/backend/requirements-agent.txt
|
||
RUN pip install --no-cache-dir -r /app/backend/requirements-agent.txt
|
||
|
||
# Optional: semantic embedding routing (большие ML-зависимости: ~500 MB+)
|
||
COPY backend/requirements-embeddings.txt /app/backend/requirements-embeddings.txt
|
||
RUN if [ "$WITH_EMBEDDINGS" = "true" ]; then \
|
||
pip install --no-cache-dir -r /app/backend/requirements-embeddings.txt; \
|
||
fi
|
||
|
||
# ── Минимальная копия backend/src/ ──────────────────────────────
|
||
# Только то, что реально импортирует агент (трассировка 2026-06-14):
|
||
# src/__init__.py — пакетный корень src
|
||
# src/core/__init__.py — пакетный корень src.core
|
||
# src/core/cot_logger.py — разделяемый логгер (stdlib-only)
|
||
# src/agent/*.py — сам агент (8 .py-файлов, плоская структура)
|
||
# Ничего из api/, models/, schemas/, services/, plugins/ — не копируем.
|
||
COPY backend/src/__init__.py /app/backend/src/__init__.py
|
||
COPY backend/src/core/__init__.py /app/backend/src/core/__init__.py
|
||
COPY backend/src/core/cot_logger.py /app/backend/src/core/cot_logger.py
|
||
COPY backend/src/core/logger.py /app/backend/src/core/logger.py
|
||
COPY backend/src/core/ws_log_handler.py /app/backend/src/core/ws_log_handler.py
|
||
COPY backend/src/agent/ /app/backend/src/agent/
|
||
|
||
# Entrypoint for corporate CA cert installation
|
||
COPY docker/certs.sh /app/docker/certs.sh
|
||
COPY docker/agent.entrypoint.sh /app/docker/agent.entrypoint.sh
|
||
RUN chmod +x /app/docker/agent.entrypoint.sh /app/docker/certs.sh
|
||
|
||
# Gradio server
|
||
ENV GRADIO_SERVER_NAME=0.0.0.0
|
||
ENV GRADIO_SERVER_PORT=7860
|
||
|
||
WORKDIR /app/backend
|
||
ENTRYPOINT ["/app/docker/agent.entrypoint.sh"]
|
||
# #endregion docker.agent.Dockerfile
|