From 3ad7ebf889f1c2ec532e9e2084c16bccfee64d97 Mon Sep 17 00:00:00 2001 From: febux Date: Sat, 22 Aug 2026 20:52:05 +0300 Subject: [PATCH] Env parsing refactoring. --- docker-compose.yml | 203 ++++++++------------------------------------- 1 file changed, 36 insertions(+), 167 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 968e56c..bd527cc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -136,66 +136,19 @@ services: condition: service_healthy minio-init: condition: service_completed_successfully + # All app config flows from .env (12-factor; see .env.example for the full + # list). New settings need NO compose changes — pydantic Settings reads + # them with code-level defaults. `environment:` below only overrides the + # values that must point at in-compose hostnames instead of localhost. + env_file: + - path: .env + required: false environment: - ENV: ${ENV:-dev} - LOG_LEVEL: ${LOG_LEVEL:-INFO} DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-contract_check}:${POSTGRES_PASSWORD:-contract_check}@postgres:5432/${POSTGRES_DB:-contract_check} REDIS_URL: redis://redis:6379/0 RABBITMQ_URL: amqp://${RABBITMQ_USER:-contract_check}:${RABBITMQ_PASS:-contract_check}@rabbitmq:5672/${RABBITMQ_VHOST:-/} S3_ENDPOINT_URL: http://minio:9000 - S3_ACCESS_KEY: ${S3_ACCESS_KEY:-contract_check} - S3_SECRET_KEY: ${S3_SECRET_KEY:-contract_check} - S3_BUCKET: ${S3_BUCKET:-contract-check-docs} - S3_REGION: ${S3_REGION:-us-east-1} - S3_SERVER_SIDE_ENCRYPTION: ${S3_SERVER_SIDE_ENCRYPTION:-false} - DOC_RETENTION_DAYS: ${DOC_RETENTION_DAYS:-7} - REFUND_POLICY: ${REFUND_POLICY:-all} - SENTRY_DSN: ${SENTRY_DSN:-} - OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-} OTEL_SERVICE_NAME: api - LLM_PROVIDER: ${LLM_PROVIDER:-ollama_cloud} - OLLAMA_HOST: ${OLLAMA_HOST:-} - OLLAMA_API_KEY: ${OLLAMA_API_KEY:-} - OLLAMA_MODEL: ${OLLAMA_MODEL:-qwen2.5:14b} - OLLAMA_FALLBACK_MODEL: ${OLLAMA_FALLBACK_MODEL:-qwen2.5:7b} - OLLAMA_TEMPERATURE: ${OLLAMA_TEMPERATURE:-0.2} - OLLAMA_NUM_PREDICT: ${OLLAMA_NUM_PREDICT:-3072} - OLLAMA_TIMEOUT: ${OLLAMA_TIMEOUT:-120} - OLLAMA_MAX_CONCURRENCY: ${OLLAMA_MAX_CONCURRENCY:-3} - YANDEXGPT_API_KEY: ${YANDEXGPT_API_KEY:-} - YANDEXGPT_FOLDER_ID: ${YANDEXGPT_FOLDER_ID:-} - YANDEXGPT_MODEL: ${YANDEXGPT_MODEL:-yandexgpt-lite} - YANDEXGPT_FALLBACK_MODEL: ${YANDEXGPT_FALLBACK_MODEL:-} - YANDEXGPT_BASE_URL: ${YANDEXGPT_BASE_URL:-https://llm.api.cloud.yandex.net} - YANDEXGPT_COMPLETION_PATH: ${YANDEXGPT_COMPLETION_PATH:-/foundationModels/v1/completion} - YANDEXGPT_TEMPERATURE: ${YANDEXGPT_TEMPERATURE:-0.2} - YANDEXGPT_MAX_TOKENS: ${YANDEXGPT_MAX_TOKENS:-3072} - YANDEXGPT_TIMEOUT: ${YANDEXGPT_TIMEOUT:-120} - YANDEXGPT_MAX_CONCURRENCY: ${YANDEXGPT_MAX_CONCURRENCY:-3} - CHUNK_SIZE_CHARS: ${CHUNK_SIZE_CHARS:-10000} - API_HOST: ${API_HOST:-0.0.0.0} - API_PORT: ${API_PORT:-8000} - API_METRICS_PORT: ${API_METRICS_PORT:-9100} - CORS_ORIGINS: ${CORS_ORIGINS:-} - TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN:-} - JWT_SECRET: ${JWT_SECRET} - JWT_ALGORITHM: ${JWT_ALGORITHM:-HS256} - JWT_ACCESS_TTL_MINUTES: ${JWT_ACCESS_TTL_MINUTES:-1440} - JWT_REFRESH_TTL_DAYS: ${JWT_REFRESH_TTL_DAYS:-30} - WEB_AUTH_ENABLED: ${WEB_AUTH_ENABLED:-true} - WEB_ADMIN_ENABLED: ${WEB_ADMIN_ENABLED:-true} - ADMIN_REQUIRED_ROLE: ${ADMIN_REQUIRED_ROLE:-admin} - ADMIN_DEFAULT_EMAIL: ${ADMIN_DEFAULT_EMAIL:-admin@contract-check.local} - ADMIN_DEFAULT_PASSWORD: ${ADMIN_DEFAULT_PASSWORD:-} - PASSWORD_RESET_TTL_MINUTES: ${PASSWORD_RESET_TTL_MINUTES:-60} - PASSWORD_MIN_LENGTH: ${PASSWORD_MIN_LENGTH:-8} - WEB_APP_BASE_URL: ${WEB_APP_BASE_URL:-http://localhost:5173} - SMTP_HOST: ${SMTP_HOST:-} - SMTP_PORT: ${SMTP_PORT:-587} - SMTP_USERNAME: ${SMTP_USERNAME:-} - SMTP_PASSWORD: ${SMTP_PASSWORD:-} - SMTP_FROM: ${SMTP_FROM:-no-reply@contract-check.local} - SMTP_USE_TLS: ${SMTP_USE_TLS:-true} ports: - "${API_PORT:-8000}:8000" - "${API_METRICS_PORT:-9100}:9100" @@ -222,29 +175,18 @@ services: condition: service_healthy minio-init: condition: service_completed_successfully + # App config flows from .env (12-factor; see .env.example). New settings + # need NO compose changes — pydantic Settings reads them with code-level + # defaults. `environment:` below only overrides the values that must point + # at in-compose hostnames instead of localhost. + env_file: + - path: .env + required: false environment: - ENV: ${ENV:-dev} - LOG_LEVEL: ${LOG_LEVEL:-INFO} DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-contract_check}:${POSTGRES_PASSWORD:-contract_check}@postgres:5432/${POSTGRES_DB:-contract_check} RABBITMQ_URL: amqp://${RABBITMQ_USER:-contract_check}:${RABBITMQ_PASS:-contract_check}@rabbitmq:5672/${RABBITMQ_VHOST:-/} S3_ENDPOINT_URL: http://minio:9000 - S3_ACCESS_KEY: ${S3_ACCESS_KEY:-contract_check} - S3_SECRET_KEY: ${S3_SECRET_KEY:-contract_check} - S3_BUCKET: ${S3_BUCKET:-contract-check-docs} - S3_REGION: ${S3_REGION:-us-east-1} - S3_SERVER_SIDE_ENCRYPTION: ${S3_SERVER_SIDE_ENCRYPTION:-false} - DOC_RETENTION_DAYS: ${DOC_RETENTION_DAYS:-7} - REFUND_POLICY: ${REFUND_POLICY:-all} - SENTRY_DSN: ${SENTRY_DSN:-} - OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-} OTEL_SERVICE_NAME: worker-extract - MQ_PREFETCH_EXTRACT: ${MQ_PREFETCH_EXTRACT:-1} - MQ_MAX_ATTEMPTS: ${MQ_MAX_ATTEMPTS:-5} - MQ_RETRY_BASE_MS: ${MQ_RETRY_BASE_MS:-2000} - TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN:-} - JWT_SECRET: ${JWT_SECRET} - JWT_ALGORITHM: ${JWT_ALGORITHM:-HS256} - JWT_ACCESS_TTL_MINUTES: ${JWT_ACCESS_TTL_MINUTES:-1440} ports: - "9101:9101" @@ -262,47 +204,18 @@ services: condition: service_healthy minio-init: condition: service_completed_successfully + # App config flows from .env (12-factor; see .env.example). New settings + # need NO compose changes — pydantic Settings reads them with code-level + # defaults. `environment:` below only overrides the values that must point + # at in-compose hostnames instead of localhost. + env_file: + - path: .env + required: false environment: - ENV: ${ENV:-dev} - LOG_LEVEL: ${LOG_LEVEL:-INFO} DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-contract_check}:${POSTGRES_PASSWORD:-contract_check}@postgres:5432/${POSTGRES_DB:-contract_check} RABBITMQ_URL: amqp://${RABBITMQ_USER:-contract_check}:${RABBITMQ_PASS:-contract_check}@rabbitmq:5672/${RABBITMQ_VHOST:-/} S3_ENDPOINT_URL: http://minio:9000 - S3_ACCESS_KEY: ${S3_ACCESS_KEY:-contract_check} - S3_SECRET_KEY: ${S3_SECRET_KEY:-contract_check} - S3_BUCKET: ${S3_BUCKET:-contract-check-docs} - S3_REGION: ${S3_REGION:-us-east-1} - REFUND_POLICY: ${REFUND_POLICY:-all} - SENTRY_DSN: ${SENTRY_DSN:-} - OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-} OTEL_SERVICE_NAME: worker-analyze - MQ_PREFETCH_ANALYZE: ${MQ_PREFETCH_ANALYZE:-3} - MQ_MAX_ATTEMPTS: ${MQ_MAX_ATTEMPTS:-5} - MQ_RETRY_BASE_MS: ${MQ_RETRY_BASE_MS:-2000} - LLM_PROVIDER: ${LLM_PROVIDER:-ollama_cloud} - OLLAMA_HOST: ${OLLAMA_HOST:-} - OLLAMA_API_KEY: ${OLLAMA_API_KEY:-} - OLLAMA_MODEL: ${OLLAMA_MODEL:-qwen2.5:14b} - OLLAMA_FALLBACK_MODEL: ${OLLAMA_FALLBACK_MODEL:-qwen2.5:7b} - OLLAMA_TEMPERATURE: ${OLLAMA_TEMPERATURE:-0.2} - OLLAMA_NUM_PREDICT: ${OLLAMA_NUM_PREDICT:-3072} - OLLAMA_TIMEOUT: ${OLLAMA_TIMEOUT:-120} - OLLAMA_MAX_CONCURRENCY: ${OLLAMA_MAX_CONCURRENCY:-3} - YANDEXGPT_API_KEY: ${YANDEXGPT_API_KEY:-} - YANDEXGPT_FOLDER_ID: ${YANDEXGPT_FOLDER_ID:-} - YANDEXGPT_MODEL: ${YANDEXGPT_MODEL:-yandexgpt-lite} - YANDEXGPT_FALLBACK_MODEL: ${YANDEXGPT_FALLBACK_MODEL:-} - YANDEXGPT_BASE_URL: ${YANDEXGPT_BASE_URL:-https://llm.api.cloud.yandex.net} - YANDEXGPT_COMPLETION_PATH: ${YANDEXGPT_COMPLETION_PATH:-/foundationModels/v1/completion} - YANDEXGPT_TEMPERATURE: ${YANDEXGPT_TEMPERATURE:-0.2} - YANDEXGPT_MAX_TOKENS: ${YANDEXGPT_MAX_TOKENS:-3072} - YANDEXGPT_TIMEOUT: ${YANDEXGPT_TIMEOUT:-120} - YANDEXGPT_MAX_CONCURRENCY: ${YANDEXGPT_MAX_CONCURRENCY:-3} - CHUNK_SIZE_CHARS: ${CHUNK_SIZE_CHARS:-10000} - TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN:-} - JWT_SECRET: ${JWT_SECRET} - JWT_ALGORITHM: ${JWT_ALGORITHM:-HS256} - JWT_ACCESS_TTL_MINUTES: ${JWT_ACCESS_TTL_MINUTES:-1440} ports: - "9102:9102" @@ -320,50 +233,18 @@ services: condition: service_healthy minio-init: condition: service_completed_successfully + # App config flows from .env (12-factor; see .env.example). New settings + # need NO compose changes — pydantic Settings reads them with code-level + # defaults. `environment:` below only overrides the values that must point + # at in-compose hostnames instead of localhost. + env_file: + - path: .env + required: false environment: - ENV: ${ENV:-dev} - LOG_LEVEL: ${LOG_LEVEL:-INFO} DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-contract_check}:${POSTGRES_PASSWORD:-contract_check}@postgres:5432/${POSTGRES_DB:-contract_check} RABBITMQ_URL: amqp://${RABBITMQ_USER:-contract_check}:${RABBITMQ_PASS:-contract_check}@rabbitmq:5672/${RABBITMQ_VHOST:-/} S3_ENDPOINT_URL: http://minio:9000 - S3_ACCESS_KEY: ${S3_ACCESS_KEY:-contract_check} - S3_SECRET_KEY: ${S3_SECRET_KEY:-contract_check} - S3_BUCKET: ${S3_BUCKET:-contract-check-docs} - S3_REGION: ${S3_REGION:-us-east-1} - REFUND_POLICY: ${REFUND_POLICY:-all} - SENTRY_DSN: ${SENTRY_DSN:-} - OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-} OTEL_SERVICE_NAME: worker-prescreen - MQ_PREFETCH_PRESCREEN: ${MQ_PREFETCH_PRESCREEN:-1} - MQ_MAX_ATTEMPTS: ${MQ_MAX_ATTEMPTS:-5} - MQ_RETRY_BASE_MS: ${MQ_RETRY_BASE_MS:-2000} - PRESCREEN_ENABLED: ${PRESCREEN_ENABLED:-true} - PRESCREEN_AUTO_APPROVE: ${PRESCREEN_AUTO_APPROVE:-false} - PRESCREEN_CONFIDENCE_THRESHOLD: ${PRESCREEN_CONFIDENCE_THRESHOLD:-0.75} - PRESCREEN_HIGH_VALUE_THRESHOLD: ${PRESCREEN_HIGH_VALUE_THRESHOLD:-100000} - LLM_PROVIDER: ${LLM_PROVIDER:-ollama_cloud} - OLLAMA_HOST: ${OLLAMA_HOST:-} - OLLAMA_API_KEY: ${OLLAMA_API_KEY:-} - OLLAMA_MODEL: ${OLLAMA_MODEL:-qwen2.5:14b} - OLLAMA_FALLBACK_MODEL: ${OLLAMA_FALLBACK_MODEL:-qwen2.5:7b} - OLLAMA_TEMPERATURE: ${OLLAMA_TEMPERATURE:-0.2} - OLLAMA_NUM_PREDICT: ${OLLAMA_NUM_PREDICT:-3072} - OLLAMA_TIMEOUT: ${OLLAMA_TIMEOUT:-120} - OLLAMA_MAX_CONCURRENCY: ${OLLAMA_MAX_CONCURRENCY:-3} - YANDEXGPT_API_KEY: ${YANDEXGPT_API_KEY:-} - YANDEXGPT_FOLDER_ID: ${YANDEXGPT_FOLDER_ID:-} - YANDEXGPT_MODEL: ${YANDEXGPT_MODEL:-yandexgpt-lite} - YANDEXGPT_FALLBACK_MODEL: ${YANDEXGPT_FALLBACK_MODEL:-} - YANDEXGPT_BASE_URL: ${YANDEXGPT_BASE_URL:-https://llm.api.cloud.yandex.net} - YANDEXGPT_COMPLETION_PATH: ${YANDEXGPT_COMPLETION_PATH:-/foundationModels/v1/completion} - YANDEXGPT_TEMPERATURE: ${YANDEXGPT_TEMPERATURE:-0.2} - YANDEXGPT_MAX_TOKENS: ${YANDEXGPT_MAX_TOKENS:-3072} - YANDEXGPT_TIMEOUT: ${YANDEXGPT_TIMEOUT:-120} - YANDEXGPT_MAX_CONCURRENCY: ${YANDEXGPT_MAX_CONCURRENCY:-3} - CHUNK_SIZE_CHARS: ${CHUNK_SIZE_CHARS:-10000} - JWT_SECRET: ${JWT_SECRET} - JWT_ALGORITHM: ${JWT_ALGORITHM:-HS256} - JWT_ACCESS_TTL_MINUTES: ${JWT_ACCESS_TTL_MINUTES:-1440} ports: - "9104:9104" @@ -377,30 +258,18 @@ services: depends_on: rabbitmq: condition: service_healthy + # App config flows from .env (12-factor; see .env.example). New settings + # need NO compose changes — pydantic Settings reads them with code-level + # defaults. `environment:` below only overrides the values that must point + # at in-compose hostnames instead of localhost. + env_file: + - path: .env + required: false environment: - ENV: ${ENV:-dev} - LOG_LEVEL: ${LOG_LEVEL:-INFO} DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-contract_check}:${POSTGRES_PASSWORD:-contract_check}@postgres:5432/${POSTGRES_DB:-contract_check} RABBITMQ_URL: amqp://${RABBITMQ_USER:-contract_check}:${RABBITMQ_PASS:-contract_check}@rabbitmq:5672/${RABBITMQ_VHOST:-/} - SENTRY_DSN: ${SENTRY_DSN:-} - OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-} - OTEL_SERVICE_NAME: worker-notify S3_ENDPOINT_URL: http://minio:9000 - S3_ACCESS_KEY: ${S3_ACCESS_KEY:-contract_check} - S3_SECRET_KEY: ${S3_SECRET_KEY:-contract_check} - MQ_PREFETCH_NOTIFY: ${MQ_PREFETCH_NOTIFY:-5} - MQ_MAX_ATTEMPTS: ${MQ_MAX_ATTEMPTS:-5} - MQ_RETRY_BASE_MS: ${MQ_RETRY_BASE_MS:-2000} - SMTP_HOST: ${SMTP_HOST:-} - SMTP_PORT: ${SMTP_PORT:-587} - SMTP_USERNAME: ${SMTP_USERNAME:-} - SMTP_PASSWORD: ${SMTP_PASSWORD:-} - SMTP_FROM: ${SMTP_FROM:-no-reply@contract-check.local} - SMTP_USE_TLS: ${SMTP_USE_TLS:-true} - WEB_APP_BASE_URL: ${WEB_APP_BASE_URL:-http://localhost:5173} - JWT_SECRET: ${JWT_SECRET} - JWT_ALGORITHM: ${JWT_ALGORITHM:-HS256} - JWT_ACCESS_TTL_MINUTES: ${JWT_ACCESS_TTL_MINUTES:-1440} + OTEL_SERVICE_NAME: worker-notify ports: - "9103:9103"