- Fix Dockerfile stub builds; compile full sources (no empty binaries) - Add ca-certificates and curl in runtime images for TLS/healthchecks - Enable RUST_LOG and RUST_BACKTRACE for all providers - Add HTTP /health healthchecks in docker-compose for ports 8000-8004 - Standardize Tushare /health to structured HealthStatus JSON - Enforce strict config validation (FINNHUB_API_KEY, TUSHARE_API_TOKEN) - Map provider API keys via .env in docker-compose - Log provider_services at API Gateway startup for diagnostics Outcome: provider containers no longer exit silently; missing keys fail fast with explicit errors; health and logs are consistent across modules.
229 lines
6.6 KiB
YAML
229 lines
6.6 KiB
YAML
services:
|
||
postgres-db:
|
||
image: timescale/timescaledb:2.15.2-pg16
|
||
container_name: fundamental-postgres
|
||
command: -c shared_preload_libraries=timescaledb
|
||
environment:
|
||
POSTGRES_USER: postgres
|
||
POSTGRES_PASSWORD: postgres
|
||
POSTGRES_DB: fundamental
|
||
volumes:
|
||
- pgdata:/var/lib/postgresql/data
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "pg_isready -U postgres -d fundamental"]
|
||
interval: 5s
|
||
timeout: 5s
|
||
retries: 10
|
||
networks:
|
||
- app-network
|
||
nats:
|
||
image: nats:2.9
|
||
volumes:
|
||
- nats_data:/data
|
||
networks:
|
||
- app-network
|
||
|
||
data-persistence-service:
|
||
build:
|
||
context: .
|
||
dockerfile: services/data-persistence-service/Dockerfile
|
||
container_name: data-persistence-service
|
||
environment:
|
||
HOST: 0.0.0.0
|
||
PORT: 3000
|
||
# Rust service connects to the internal DB service name
|
||
DATABASE_URL: postgresql://postgres:postgres@postgres-db:5432/fundamental
|
||
RUST_LOG: info
|
||
RUST_BACKTRACE: "1"
|
||
depends_on:
|
||
postgres-db:
|
||
condition: service_healthy
|
||
# If you prefer live-reload or local code mount, consider switching to a dev Dockerfile.
|
||
# volumes:
|
||
# - ./:/workspace
|
||
networks:
|
||
- app-network
|
||
|
||
|
||
frontend:
|
||
build:
|
||
context: .
|
||
dockerfile: frontend/Dockerfile
|
||
container_name: fundamental-frontend
|
||
working_dir: /workspace/frontend
|
||
command: npm run dev
|
||
environment:
|
||
# 让 Next 的 API 路由代理到新的 api-gateway
|
||
NEXT_PUBLIC_BACKEND_URL: http://api-gateway:4000/v1
|
||
# SSR 内部访问自身 API 的内部地址,避免使用 x-forwarded-host 导致访问宿主机端口
|
||
FRONTEND_INTERNAL_URL: http://fundamental-frontend:3001
|
||
BACKEND_INTERNAL_URL: http://api-gateway:4000/v1
|
||
NODE_ENV: development
|
||
NEXT_TELEMETRY_DISABLED: "1"
|
||
volumes:
|
||
- ./:/workspace
|
||
# 隔离 node_modules,避免与宿主机冲突
|
||
- frontend_node_modules:/workspace/frontend/node_modules
|
||
ports:
|
||
- "13001:3001"
|
||
depends_on:
|
||
- api-gateway
|
||
networks:
|
||
- app-network
|
||
|
||
|
||
api-gateway:
|
||
build:
|
||
context: .
|
||
dockerfile: services/api-gateway/Dockerfile
|
||
container_name: api-gateway
|
||
restart: unless-stopped
|
||
environment:
|
||
SERVER_PORT: 4000
|
||
NATS_ADDR: nats://nats:4222
|
||
DATA_PERSISTENCE_SERVICE_URL: http://data-persistence-service:3000/api/v1
|
||
# provider_services via explicit JSON for deterministic parsing
|
||
PROVIDER_SERVICES: '["http://alphavantage-provider-service:8000", "http://tushare-provider-service:8001", "http://finnhub-provider-service:8002", "http://yfinance-provider-service:8003"]'
|
||
RUST_LOG: info,axum=info
|
||
RUST_BACKTRACE: "1"
|
||
depends_on:
|
||
- nats
|
||
- data-persistence-service
|
||
- alphavantage-provider-service
|
||
- tushare-provider-service
|
||
- finnhub-provider-service
|
||
- yfinance-provider-service
|
||
networks:
|
||
- app-network
|
||
|
||
alphavantage-provider-service:
|
||
build:
|
||
context: .
|
||
dockerfile: services/alphavantage-provider-service/Dockerfile
|
||
container_name: alphavantage-provider-service
|
||
environment:
|
||
SERVER_PORT: 8000
|
||
NATS_ADDR: nats://nats:4222
|
||
DATA_PERSISTENCE_SERVICE_URL: http://data-persistence-service:3000/api/v1
|
||
ALPHAVANTAGE_API_KEY: ${ALPHAVANTAGE_API_KEY}
|
||
RUST_LOG: info,axum=info
|
||
RUST_BACKTRACE: "1"
|
||
depends_on:
|
||
- nats
|
||
- data-persistence-service
|
||
networks:
|
||
- app-network
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "curl -fsS http://localhost:8000/health >/dev/null || exit 1"]
|
||
interval: 5s
|
||
timeout: 5s
|
||
retries: 12
|
||
|
||
tushare-provider-service:
|
||
build:
|
||
context: .
|
||
dockerfile: services/tushare-provider-service/Dockerfile
|
||
container_name: tushare-provider-service
|
||
environment:
|
||
SERVER_PORT: 8001
|
||
NATS_ADDR: nats://nats:4222
|
||
DATA_PERSISTENCE_SERVICE_URL: http://data-persistence-service:3000/api/v1
|
||
TUSHARE_API_URL: http://api.waditu.com
|
||
# Please provide your Tushare token via .env
|
||
TUSHARE_API_TOKEN: ${TUSHARE_API_TOKEN}
|
||
RUST_LOG: info,axum=info
|
||
RUST_BACKTRACE: "1"
|
||
depends_on:
|
||
- nats
|
||
- data-persistence-service
|
||
networks:
|
||
- app-network
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "curl -fsS http://localhost:8001/health >/dev/null || exit 1"]
|
||
interval: 5s
|
||
timeout: 5s
|
||
retries: 12
|
||
|
||
finnhub-provider-service:
|
||
build:
|
||
context: .
|
||
dockerfile: services/finnhub-provider-service/Dockerfile
|
||
container_name: finnhub-provider-service
|
||
environment:
|
||
SERVER_PORT: 8002
|
||
NATS_ADDR: nats://nats:4222
|
||
DATA_PERSISTENCE_SERVICE_URL: http://data-persistence-service:3000/api/v1
|
||
FINNHUB_API_URL: https://finnhub.io/api/v1
|
||
# Please provide your Finnhub token in .env file
|
||
FINNHUB_API_KEY: ${FINNHUB_API_KEY}
|
||
RUST_LOG: info,axum=info
|
||
RUST_BACKTRACE: "1"
|
||
depends_on:
|
||
- nats
|
||
- data-persistence-service
|
||
networks:
|
||
- app-network
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "curl -fsS http://localhost:8002/health >/dev/null || exit 1"]
|
||
interval: 5s
|
||
timeout: 5s
|
||
retries: 12
|
||
|
||
yfinance-provider-service:
|
||
build:
|
||
context: .
|
||
dockerfile: services/yfinance-provider-service/Dockerfile
|
||
container_name: yfinance-provider-service
|
||
environment:
|
||
SERVER_PORT: 8003
|
||
NATS_ADDR: nats://nats:4222
|
||
DATA_PERSISTENCE_SERVICE_URL: http://data-persistence-service:3000/api/v1
|
||
RUST_LOG: info,axum=info
|
||
RUST_BACKTRACE: "1"
|
||
depends_on:
|
||
- nats
|
||
- data-persistence-service
|
||
networks:
|
||
- app-network
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "curl -fsS http://localhost:8003/health >/dev/null || exit 1"]
|
||
interval: 5s
|
||
timeout: 5s
|
||
retries: 12
|
||
|
||
report-generator-service:
|
||
build:
|
||
context: .
|
||
dockerfile: services/report-generator-service/Dockerfile
|
||
container_name: report-generator-service
|
||
environment:
|
||
SERVER_PORT: 8004
|
||
NATS_ADDR: nats://nats:4222
|
||
DATA_PERSISTENCE_SERVICE_URL: http://data-persistence-service:3000/api/v1
|
||
RUST_LOG: info,axum=info
|
||
RUST_BACKTRACE: "1"
|
||
depends_on:
|
||
- nats
|
||
- data-persistence-service
|
||
networks:
|
||
- app-network
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "curl -fsS http://localhost:8004/health >/dev/null || exit 1"]
|
||
interval: 5s
|
||
timeout: 5s
|
||
retries: 12
|
||
|
||
# =================================================================
|
||
# Python Services (Legacy - to be replaced)
|
||
# =================================================================
|
||
|
||
volumes:
|
||
pgdata:
|
||
frontend_node_modules:
|
||
nats_data:
|
||
|
||
networks:
|
||
app-network:
|
||
|
||
|