feat(compose): internal db network and api healthcheck

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>
This commit is contained in:
Vadim Malanov
2026-07-07 09:50:31 +03:00
parent 1c1dceeee2
commit 221cdc4d0f
3 changed files with 39 additions and 3 deletions

View File

@@ -37,10 +37,22 @@ x-common-env: &common-env
CORS_ALLOWED_ORIGINS: ${CORS_ALLOWED_ORIGINS:-http://localhost:5273,http://localhost:4173}
API_KEY: ${API_KEY:-}
# Module-contract isolation: data services live on the internal-only
# legacyhub_db network (the same name docker-compose.teamhub.yml uses, so the
# federation overlay composes without a parallel network). In dev they also
# join edge so host-published ports keep working; the prod overlay pins them
# to legacyhub_db only. api/worker need edge for the published API port and
# HuggingFace model downloads.
networks:
legacyhub_db:
internal: true
edge: {}
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
networks: [legacyhub_db, edge]
environment:
POSTGRES_DB: ${POSTGRES_DB:-legacyhub}
POSTGRES_USER: ${POSTGRES_USER:-legacyhub}
@@ -58,6 +70,7 @@ services:
minio:
image: minio/minio:RELEASE.2024-08-29T01-40-52Z
restart: unless-stopped
networks: [legacyhub_db, edge]
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: ${MINIO_ACCESS_KEY:-legacyhub}
@@ -76,6 +89,7 @@ services:
opensearch:
image: opensearchproject/opensearch:2.15.0
restart: unless-stopped
networks: [legacyhub_db, edge]
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
@@ -103,6 +117,7 @@ services:
qdrant:
image: qdrant/qdrant:v1.11.3
restart: unless-stopped
networks: [legacyhub_db, edge]
ports:
- "6333:6333"
- "6334:6334"
@@ -117,6 +132,7 @@ services:
redis:
image: redis:7-alpine
restart: unless-stopped
networks: [legacyhub_db, edge]
ports:
- "6379:6379"
volumes:
@@ -133,11 +149,20 @@ services:
dockerfile: docker/Dockerfile
image: legacyhub/api:latest
restart: unless-stopped
networks: [legacyhub_db, edge]
environment:
<<: *common-env
APP_HOST: 0.0.0.0
APP_PORT: 8000
command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
healthcheck:
# /api/v1/health is liveness: it answers HTTP 200 even when a dependency
# is degraded, so the container is not restart-looped on data-store issues.
test: ["CMD", "curl", "-fsS", "http://localhost:8000/api/v1/health"]
interval: 30s
timeout: 10s
retries: 5
start_period: 60s
ports:
# Host port 8050 avoids the 8000 collision (SalesHUB / old dispatch dev).
# Container still listens on 8000. Overridden by ${API_HOST_PORT}.
@@ -164,6 +189,7 @@ services:
dockerfile: docker/Dockerfile
image: legacyhub/api:latest
restart: unless-stopped
networks: [legacyhub_db, edge]
environment:
<<: *common-env
command: ["celery", "-A", "app.workers.celery_app", "worker", "--loglevel=INFO", "--concurrency=2"]