feat(infra): api-gateway 环境变量补全 + build context 修复 + docker-compose.test 新增
This commit is contained in:
@@ -32,8 +32,11 @@ ADMIN_PORTAL_PORT=4003
|
|||||||
KAFKA_BROKERS=
|
KAFKA_BROKERS=
|
||||||
|
|
||||||
# ============ push-gateway(WebSocket 推送服务)============
|
# ============ push-gateway(WebSocket 推送服务)============
|
||||||
# /internal/push 鉴权 token(msg 服务调用时需携带 X-Internal-Token 头)
|
# /internal/push 鉴权 token(msg 服务调用时需携带 X-Internal-Key 头,ARB-013)
|
||||||
INTERNAL_API_TOKEN=CHANGE_ME_TO_STRONG_INTERNAL_TOKEN
|
# PUSH_INTERNAL_TOKEN 是 v2 规范环境变量;INTERNAL_API_TOKEN 作为向后兼容别名仍被接受
|
||||||
|
PUSH_INTERNAL_TOKEN=CHANGE_ME_TO_STRONG_INTERNAL_TOKEN
|
||||||
|
# 向后兼容别名(留空则使用 PUSH_INTERNAL_TOKEN;设置后会回退到此值)
|
||||||
|
INTERNAL_API_TOKEN=
|
||||||
# WebSocket 允许的 Origin 白名单(逗号分隔)
|
# WebSocket 允许的 Origin 白名单(逗号分隔)
|
||||||
WS_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:4000,http://localhost:4001,http://localhost:4002,http://localhost:4003
|
WS_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:4000,http://localhost:4001,http://localhost:4002,http://localhost:4003
|
||||||
# push-gateway 对外端口
|
# push-gateway 对外端口
|
||||||
|
|||||||
@@ -23,25 +23,31 @@ services:
|
|||||||
# ============================================================
|
# ============================================================
|
||||||
api-gateway:
|
api-gateway:
|
||||||
build:
|
build:
|
||||||
context: ./repo/services/api-gateway
|
context: ./repo
|
||||||
dockerfile: Dockerfile
|
dockerfile: services/api-gateway/Dockerfile
|
||||||
container_name: edu-api-gateway
|
container_name: edu-api-gateway
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
API_GATEWAY_PORT: ${API_GATEWAY_PORT:-8080}
|
API_GATEWAY_PORT: ${API_GATEWAY_PORT:-8080}
|
||||||
|
ENV: production
|
||||||
JWT_SECRET: ${JWT_SECRET}
|
JWT_SECRET: ${JWT_SECRET}
|
||||||
JWT_ISSUER: ${JWT_ISSUER:-next-edu-cloud}
|
JWT_ISSUER: ${JWT_ISSUER:-next-edu-cloud}
|
||||||
JWT_AUDIENCE: ${JWT_AUDIENCE:-next-edu-cloud}
|
JWT_AUDIENCE: ${JWT_AUDIENCE:-next-edu-cloud}
|
||||||
|
# RS256 公钥端点(非 DevMode 下必填,config.go W7 防护)
|
||||||
|
IAM_JWKS_URL: http://iam:3002/v1/iam/.well-known/jwks.json
|
||||||
# 生产环境强制关闭 dev-token 旁路
|
# 生产环境强制关闭 dev-token 旁路
|
||||||
DEV_MODE: "false"
|
DEV_MODE: "false"
|
||||||
CLASSES_SERVICE_URL: http://classes:3001
|
CLASSES_SERVICE_URL: http://classes:3001
|
||||||
IAM_SERVICE_URL: http://iam:3002
|
IAM_SERVICE_URL: http://iam:3002
|
||||||
TEACHER_BFF_URL: http://teacher-bff:3003
|
TEACHER_BFF_URL: http://teacher-bff:3003
|
||||||
|
STUDENT_BFF_URL: http://student-bff:3009
|
||||||
|
PARENT_BFF_URL: http://parent-bff:3010
|
||||||
CORE_EDU_SERVICE_URL: http://core-edu:3004
|
CORE_EDU_SERVICE_URL: http://core-edu:3004
|
||||||
CONTENT_SERVICE_URL: http://content:3005
|
CONTENT_SERVICE_URL: http://content:3005
|
||||||
DATA_ANA_SERVICE_URL: http://data-ana:3006
|
DATA_ANA_SERVICE_URL: http://data-ana:3006
|
||||||
MSG_SERVICE_URL: http://msg:3007
|
MSG_SERVICE_URL: http://msg:3007
|
||||||
AI_SERVICE_URL: http://ai:3008
|
AI_SERVICE_URL: http://ai:3008
|
||||||
|
CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000,http://localhost:4000,http://localhost:4001,http://localhost:4002,http://localhost:4003}
|
||||||
OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://otel-collector:4318}
|
OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://otel-collector:4318}
|
||||||
LOG_LEVEL: ${LOG_LEVEL:-info}
|
LOG_LEVEL: ${LOG_LEVEL:-info}
|
||||||
ports:
|
ports:
|
||||||
@@ -116,9 +122,19 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
PORT: 3003
|
PORT: 3003
|
||||||
|
TEACHER_BFF_DEV_MODE: "false"
|
||||||
|
REDIS_URL: ${REDIS_URL}
|
||||||
|
IAM_GRPC_TARGET: iam:50052
|
||||||
IAM_SERVICE_URL: http://iam:3002
|
IAM_SERVICE_URL: http://iam:3002
|
||||||
CLASSES_SERVICE_URL: http://classes:3001
|
CLASSES_SERVICE_URL: http://classes:3001
|
||||||
|
CORE_EDU_GRPC_TARGET: core-edu:50053
|
||||||
CORE_EDU_SERVICE_URL: http://core-edu:3004
|
CORE_EDU_SERVICE_URL: http://core-edu:3004
|
||||||
|
CONTENT_GRPC_TARGET: content:50054
|
||||||
|
DATA_ANA_GRPC_TARGET: data-ana:50055
|
||||||
|
MSG_GRPC_TARGET: msg:50056
|
||||||
|
MSG_SERVICE_URL: http://msg:3007
|
||||||
|
AI_GRPC_TARGET: ai:50058
|
||||||
|
OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://otel-collector:4318}
|
||||||
LOG_LEVEL: ${LOG_LEVEL:-info}
|
LOG_LEVEL: ${LOG_LEVEL:-info}
|
||||||
NODE_ENV: production
|
NODE_ENV: production
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -280,9 +296,12 @@ services:
|
|||||||
JWT_SECRET: ${JWT_SECRET}
|
JWT_SECRET: ${JWT_SECRET}
|
||||||
REDIS_URL: ${REDIS_URL}
|
REDIS_URL: ${REDIS_URL}
|
||||||
KAFKA_BROKERS: ${KAFKA_BROKERS:-kafka:29092}
|
KAFKA_BROKERS: ${KAFKA_BROKERS:-kafka:29092}
|
||||||
KAFKA_NOTIFICATION_TOPIC: edu.notification.requested
|
# ARB-013 canonical topic name (v2 alignment with msg Outbox publisher).
|
||||||
|
KAFKA_NOTIFICATION_TOPIC: edu.notify.notification.sent
|
||||||
KAFKA_CONSUMER_GROUP: push-gateway
|
KAFKA_CONSUMER_GROUP: push-gateway
|
||||||
INTERNAL_API_TOKEN: ${INTERNAL_API_TOKEN:-edu-internal-token}
|
# PUSH_INTERNAL_TOKEN is the canonical env var (ARB-013 alignment with
|
||||||
|
# msg). INTERNAL_API_TOKEN kept as backward-compat alias.
|
||||||
|
PUSH_INTERNAL_TOKEN: ${PUSH_INTERNAL_TOKEN:-${INTERNAL_API_TOKEN:-edu-internal-token}}
|
||||||
JWKS_URL: http://iam:3002/v1/iam/.well-known/jwks.json
|
JWKS_URL: http://iam:3002/v1/iam/.well-known/jwks.json
|
||||||
WS_ALLOWED_ORIGINS: ${WS_ALLOWED_ORIGINS:-http://localhost:3000,http://localhost:4000,http://localhost:4001,http://localhost:4002,http://localhost:4003}
|
WS_ALLOWED_ORIGINS: ${WS_ALLOWED_ORIGINS:-http://localhost:3000,http://localhost:4000,http://localhost:4001,http://localhost:4002,http://localhost:4003}
|
||||||
MAX_CONNS_PER_USER: "5"
|
MAX_CONNS_PER_USER: "5"
|
||||||
|
|||||||
134
infra/docker-compose.test.yml
Normal file
134
infra/docker-compose.test.yml
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
# 本地测试用 Docker Compose(iam + teacher-bff + ai 联调)
|
||||||
|
# 使用方式:
|
||||||
|
# docker compose -f infra/docker-compose.test.yml up -d --build
|
||||||
|
#
|
||||||
|
# 依赖:edu-full_default 网络已存在(MySQL/Redis/Kafka 已在该网络)
|
||||||
|
# 网络:复用 edu-full_default,使各服务可直连 edu-mysql/edu-redis/edu-kafka
|
||||||
|
name: edu-test
|
||||||
|
|
||||||
|
services:
|
||||||
|
iam:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: services/iam/Dockerfile
|
||||||
|
container_name: edu-iam-test
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
# 生产模式:避免 pino-pretty 依赖(pruned by --prod)
|
||||||
|
# DEV_MODE=true 仍可旁路鉴权
|
||||||
|
NODE_ENV: production
|
||||||
|
PORT: "3002"
|
||||||
|
GRPC_PORT: "50052"
|
||||||
|
DATABASE_URL: mysql://edu:changeme@edu-mysql:3306/next_edu_cloud
|
||||||
|
REDIS_URL: redis://edu-redis:6379
|
||||||
|
IAM_PRIVATE_KEY_PATH: /app/keys/iam-private.pem
|
||||||
|
IAM_PUBLIC_KEY_PATH: /app/keys/iam-public.pem
|
||||||
|
JWT_ISSUER: next-edu-cloud
|
||||||
|
JWT_AUDIENCE: next-edu-cloud
|
||||||
|
JWT_KEY_ID: iam-rs256-v1
|
||||||
|
KAFKA_BROKERS: kafka:29092
|
||||||
|
KAFKA_CLIENT_ID: iam-service
|
||||||
|
LOG_LEVEL: info
|
||||||
|
# 开发模式:接受 dev-token 旁路鉴权
|
||||||
|
DEV_MODE: "true"
|
||||||
|
ports:
|
||||||
|
- "3002:3002"
|
||||||
|
- "50052:50052"
|
||||||
|
volumes:
|
||||||
|
- ../keys:/app/keys:ro
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--quiet", "--spider", "http://localhost:3002/healthz"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
start_period: 30s
|
||||||
|
retries: 5
|
||||||
|
networks:
|
||||||
|
- edu-full
|
||||||
|
|
||||||
|
teacher-bff:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: services/teacher-bff/Dockerfile
|
||||||
|
container_name: edu-teacher-bff-test
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
PORT: "3003"
|
||||||
|
GRAPHQL_PATH: /graphql
|
||||||
|
TEACHER_BFF_DEV_MODE: "true"
|
||||||
|
REDIS_URL: redis://edu-redis:6379
|
||||||
|
IAM_GRPC_TARGET: iam:50052
|
||||||
|
IAM_SERVICE_URL: http://iam:3002
|
||||||
|
CORE_EDU_GRPC_TARGET: core-edu:50053
|
||||||
|
CONTENT_GRPC_TARGET: content:50054
|
||||||
|
DATA_ANA_GRPC_TARGET: data-ana:50055
|
||||||
|
MSG_GRPC_TARGET: msg:50056
|
||||||
|
MSG_SERVICE_URL: http://msg:3007
|
||||||
|
AI_GRPC_TARGET: ai:50058
|
||||||
|
LOG_LEVEL: info
|
||||||
|
ports:
|
||||||
|
- "3003:3003"
|
||||||
|
depends_on:
|
||||||
|
iam:
|
||||||
|
condition: service_healthy
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--quiet", "--spider", "http://localhost:3003/healthz"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
start_period: 20s
|
||||||
|
retries: 5
|
||||||
|
networks:
|
||||||
|
- edu-full
|
||||||
|
|
||||||
|
ai:
|
||||||
|
build:
|
||||||
|
context: ../services/ai
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: edu-ai-test
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
# HTTP/gRPC 端口
|
||||||
|
HTTP_PORT: "3008"
|
||||||
|
GRPC_PORT: "50058"
|
||||||
|
# 开发模式(旁路鉴权,dev-token)
|
||||||
|
DEV_MODE: "true"
|
||||||
|
LOG_LEVEL: info
|
||||||
|
# 基础设施
|
||||||
|
REDIS_URL: redis://edu-redis:6379/0
|
||||||
|
KAFKA_BOOTSTRAP_SERVERS: kafka:29092
|
||||||
|
KAFKA_AI_USAGE_TOPIC: edu.ai.usage
|
||||||
|
# 下游 gRPC 端点(edu-full_default 网络内服务名解析)
|
||||||
|
# content 服务未启动 → connect 失败但不阻断启动,调用时抛 AIError
|
||||||
|
CONTENT_GRPC_ENDPOINT: content:50054
|
||||||
|
DATA_ANA_GRPC_ENDPOINT: data-ana:50055
|
||||||
|
IAM_GRPC_ENDPOINT: iam:50052
|
||||||
|
# LLM 配置(测试环境不配 API key,LLM 功能降级,HTTP 端点仍可调)
|
||||||
|
OPENAI_API_KEY: ""
|
||||||
|
OPENAI_BASE_URL: https://api.openai.com/v1
|
||||||
|
ANTHROPIC_API_KEY: ""
|
||||||
|
BAICHUAN_API_KEY: ""
|
||||||
|
OLLAMA_BASE_URL: ""
|
||||||
|
LLM_PROVIDER_PRIORITY: openai,anthropic,baichuan,local_ollama
|
||||||
|
DEFAULT_CHAT_MODEL: gpt-4o-mini
|
||||||
|
DEFAULT_QUESTION_MODEL: gpt-4o-mini
|
||||||
|
# 可观测性(jaeger 已在 edu-full_default 网络中)
|
||||||
|
OTEL_EXPORTER_OTLP_ENDPOINT: http://edu-jaeger:4318
|
||||||
|
ports:
|
||||||
|
- "3008:3008"
|
||||||
|
- "50058:50058"
|
||||||
|
depends_on:
|
||||||
|
iam:
|
||||||
|
condition: service_healthy
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:3008/healthz')"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
start_period: 30s
|
||||||
|
retries: 5
|
||||||
|
networks:
|
||||||
|
- edu-full
|
||||||
|
|
||||||
|
networks:
|
||||||
|
edu-full:
|
||||||
|
external: true
|
||||||
|
name: edu-full_default
|
||||||
Reference in New Issue
Block a user