Files
danyang-match/infrastructure/docker-compose.staging.yml
T
WorkBuddy 5715987049 fix(infra): 修复健康探针的 IPv4/IPv6 解析歧义(nginx 假 unhealthy)
问题:本地完整栈起齐后 nginx 容器报 unhealthy,但宿主 curl
http://localhost:6688/nginx-health 返回 200 —— 探针与实际服务不一致。

根因(实证,非推断):
- nginx 的 `listen 80` 只绑 IPv4:容器内 netstat 显示 0.0.0.0:80,无 [::]:80;
- /etc/hosts 中存在 `::1 localhost`,busybox wget 解析 localhost 时优先取 ::1;
- 容器内实测:wget http://127.0.0.1/nginx-health → ok
              wget http://localhost/nginx-health  → Connection refused。

即探针地址与服务的实际绑定族不一致,属「探针与被探对象脱钩」的假告警,
并会连带拖垮 depends_on: service_healthy 的下游等待。
(backend 之所以此前一直 healthy,是因为 Java 恰好双栈监听 :::8080 —— 属偶然,不应被依赖。)

修复:
- infrastructure/docker-compose.yml:nginx 与 backend 探针改用 127.0.0.1,并各加注释写明理由;
- infrastructure/docker-compose.staging.yml:backend 探针的同类写法一并改(staging 栈未起,
  未经运行验证,仅保持写法同构)。

验证:
- docker compose config 通过;nginx 重建后 State.Health = healthy(FailingStreak=0,探针 ExitCode=0);
- 链路回归:/admin/ 200(877B)、/admin/assets/index-CDxMNwaf.js 200(1,267,697B)、
  /nginx-health 200、/api/v1/health/live 200;/admin 与根路径均 301 → /admin/;
- 活栈 E2E 49 passed;UI 契约门禁 14/14 PASS。
2026-09-18 22:27:26 +08:00

104 lines
3.3 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Staging Docker Compose(预发环境,仅开发/测试)
version: '3.8'
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: danyang_match_staging
POSTGRES_USER: staging
POSTGRES_PASSWORD: staging_dev_password_change_me
ports:
- "5433:5432"
volumes:
- postgres_staging_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U staging -d danyang_match_staging"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
ports:
- "6380:6379"
command: redis-server --appendonly yes --requirepass staging-redis-pass-change-me
volumes:
- redis_staging_data:/data
healthcheck:
test: ["CMD", "redis-cli", "-a", "staging-redis-pass-change-me", "ping"]
interval: 10s
timeout: 5s
retries: 5
minio:
image: minio/minio:latest
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: staging
MINIO_ROOT_PASSWORD: staging_dev_password
ports:
- "9010:9000"
- "9011:9001"
volumes:
- minio_staging_data:/data
backend:
build:
context: ../backend
dockerfile: Dockerfile
container_name: danyang-match-staging-backend
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
environment:
SPRING_PROFILES_ACTIVE: staging
DB_HOST: postgres
DB_PORT: 5432
DB_NAME: danyang_match_staging
DB_USER: staging
DB_PASSWORD: staging_dev_password_change_me
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_PASSWORD: staging-redis-pass-change-me
MINIO_ENDPOINT: http://minio:9000
MINIO_ACCESS_KEY: staging
MINIO_SECRET_KEY: staging_dev_password
JWT_ACCESS_SECRET: staging-access-secret-dev-only
JWT_REFRESH_SECRET: staging-refresh-secret-dev-only
CHECKIN_TOKEN_SECRET: staging-checkin-secret-dev-only
ENCRYPTION_KEY: 32539f3d2fa8123dcec899cc3dbee7347034123a126ac22fcb4702e10c454d50
FEATURES_APPEAL_ENABLED: "true"
ports:
- "8081:8080"
healthcheck:
# 探针用 127.0.0.1 而非 localhost:busybox wget 解析 localhost 时可能优先取 ::1,
# 而服务若只绑 IPv4 会导致探针假失败(本地栈的 nginx 已实测踩到)。
test: ["CMD-SHELL", "curl -f http://127.0.0.1:8080/api/v1/health/ready || exit 1"]
interval: 30s
timeout: 10s
retries: 3
admin-web:
build:
context: ../admin-web
dockerfile: Dockerfile
container_name: danyang-match-staging-admin
depends_on:
- backend
ports:
# staging 与生产同机共存,全部端口按「生产 + 1」错开(5433/6380/8081/13521)。
# 生产管理端为 13520(admin-web/vite.config.ts + docker-compose.prod.yml),
# 故此处为 13521 —— 与 tests/uat/run-uat.sh 的 UAT_ADMIN_URL 默认值一致,
# 两处均由 ui-tests/ui-document-baseline-contracts.mjs 钉住。
# 管理端构建产物部署在 /admin/ 子路径下(见 admin-web/vite.config.ts 的 base),
# 故直连访问地址为 http://localhost:13521/admin/ 。
- "13521:80"
volumes:
postgres_staging_data:
redis_staging_data:
minio_staging_data: