Add the internal-only legacyhub_db network (same name the teamhub federation overlay already uses) plus an edge network to the base compose. Dev keeps host-published ports via edge; the prod overlay pins data services to legacyhub_db only, closing the module-contract gap (DB/broker on internal networks). Add a curl liveness healthcheck for the api container against /api/v1/health. Verified: docker compose config for dev, prod and prod+teamhub stacks; per-service network/port/healthcheck matrix inspected via config --format json. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
110 lines
3.9 KiB
YAML
110 lines
3.9 KiB
YAML
# Production overlay for LegacyHUB.
|
|
#
|
|
# Usage:
|
|
# cp .env.prod.example .env.prod
|
|
# $EDITOR .env.prod # rotate every credential
|
|
# docker compose \
|
|
# -f docker-compose.yml -f docker-compose.prod.yml \
|
|
# --env-file .env.prod \
|
|
# up -d --build --force-recreate
|
|
#
|
|
# This overlay narrows the dev-friendly defaults:
|
|
# - removes published ports from data services (only api stays public);
|
|
# - pins data services to the internal-only docker network (no egress);
|
|
# - turns on the OpenSearch security plugin and forces an admin password;
|
|
# - requires CORS_ALLOWED_ORIGINS to be set (no localhost fallback);
|
|
# - bumps Java + worker concurrency for real workloads;
|
|
# - drops the MinIO console.
|
|
|
|
services:
|
|
postgres:
|
|
networks: !override [legacyhub_db]
|
|
ports: !reset []
|
|
environment:
|
|
POSTGRES_DB: ${POSTGRES_DB}
|
|
POSTGRES_USER: ${POSTGRES_USER}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set}
|
|
restart: always
|
|
|
|
minio:
|
|
command: server /data
|
|
networks: !override [legacyhub_db]
|
|
ports: !reset []
|
|
environment:
|
|
MINIO_ROOT_USER: ${MINIO_ACCESS_KEY:?MINIO_ACCESS_KEY must be set}
|
|
MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY:?MINIO_SECRET_KEY must be set}
|
|
restart: always
|
|
|
|
opensearch:
|
|
networks: !override [legacyhub_db]
|
|
ports: !reset []
|
|
environment:
|
|
- discovery.type=single-node
|
|
- bootstrap.memory_lock=true
|
|
- "OPENSEARCH_JAVA_OPTS=-Xms2g -Xmx2g"
|
|
- DISABLE_INSTALL_DEMO_CONFIG=true
|
|
- plugins.security.disabled=false
|
|
- OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_ADMIN_PASSWORD:?OPENSEARCH_ADMIN_PASSWORD must be set}
|
|
restart: always
|
|
|
|
qdrant:
|
|
networks: !override [legacyhub_db]
|
|
ports: !reset []
|
|
environment:
|
|
QDRANT__SERVICE__API_KEY: ${QDRANT_API_KEY:?QDRANT_API_KEY must be set}
|
|
restart: always
|
|
|
|
redis:
|
|
networks: !override [legacyhub_db]
|
|
ports: !reset []
|
|
restart: always
|
|
|
|
api:
|
|
environment:
|
|
<<: &prod-env
|
|
POSTGRES_HOST: ${POSTGRES_HOST}
|
|
POSTGRES_PORT: ${POSTGRES_PORT}
|
|
POSTGRES_DB: ${POSTGRES_DB}
|
|
POSTGRES_USER: ${POSTGRES_USER}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
MINIO_ENDPOINT: ${MINIO_ENDPOINT}
|
|
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY}
|
|
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY}
|
|
MINIO_BUCKET_ORIGINALS: ${MINIO_BUCKET_ORIGINALS}
|
|
MINIO_BUCKET_DERIVED: ${MINIO_BUCKET_DERIVED}
|
|
MINIO_SECURE: "true"
|
|
OPENSEARCH_HOST: ${OPENSEARCH_HOST}
|
|
OPENSEARCH_PORT: ${OPENSEARCH_PORT}
|
|
OPENSEARCH_USE_SSL: "true"
|
|
OPENSEARCH_VERIFY_CERTS: "true"
|
|
OPENSEARCH_USER: ${OPENSEARCH_USER}
|
|
OPENSEARCH_PASSWORD: ${OPENSEARCH_PASSWORD}
|
|
OPENSEARCH_INDEX_CHUNKS: ${OPENSEARCH_INDEX_CHUNKS}
|
|
QDRANT_HOST: ${QDRANT_HOST}
|
|
QDRANT_PORT: ${QDRANT_PORT}
|
|
QDRANT_API_KEY: ${QDRANT_API_KEY}
|
|
QDRANT_COLLECTION_CHUNKS: ${QDRANT_COLLECTION_CHUNKS}
|
|
REDIS_URL: ${REDIS_URL}
|
|
OCR_LANGUAGES: ${OCR_LANGUAGES}
|
|
OCR_ENABLED: ${OCR_ENABLED}
|
|
DOCLING_OCR_ENABLED: ${DOCLING_OCR_ENABLED}
|
|
MAX_DOCUMENT_TIMEOUT_SECONDS: ${MAX_DOCUMENT_TIMEOUT_SECONDS}
|
|
EMBEDDING_MODEL: ${EMBEDDING_MODEL}
|
|
EMBEDDING_DEVICE: ${EMBEDDING_DEVICE}
|
|
RERANKER_MODEL: ${RERANKER_MODEL}
|
|
RERANKER_DEVICE: ${RERANKER_DEVICE}
|
|
RERANKER_ENABLED: ${RERANKER_ENABLED}
|
|
APP_ENV: ${APP_ENV:-prod}
|
|
APP_LOG_LEVEL: ${APP_LOG_LEVEL}
|
|
APP_INPUT_DIR: /data/input
|
|
APP_WORK_DIR: /data/work
|
|
CORS_ALLOWED_ORIGINS: ${CORS_ALLOWED_ORIGINS:?CORS_ALLOWED_ORIGINS must be set (no * in production)}
|
|
API_KEY: ${API_KEY:?API_KEY must be set in production}
|
|
restart: always
|
|
|
|
worker:
|
|
command: ["celery", "-A", "app.workers.celery_app", "worker", "--loglevel=INFO", "--concurrency=4"]
|
|
environment:
|
|
<<: *prod-env
|
|
restart: always
|