2026-09-14 10:02:34 +08:00
|
|
|
|
# 丹阳公益婚恋服务平台 - 本地完整环境
|
2026-09-10 10:58:43 +08:00
|
|
|
|
|
|
|
|
|
|
services:
|
|
|
|
|
|
postgres:
|
|
|
|
|
|
image: postgres:16-alpine
|
|
|
|
|
|
container_name: danyang-match-postgres
|
|
|
|
|
|
environment:
|
|
|
|
|
|
POSTGRES_DB: danyang_match
|
|
|
|
|
|
POSTGRES_USER: postgres
|
|
|
|
|
|
POSTGRES_PASSWORD: ${DB_PASSWORD:?请在本地 .env 设置 DB_PASSWORD}
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "5434:5432"
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- postgres_data:/var/lib/postgresql/data
|
|
|
|
|
|
healthcheck:
|
|
|
|
|
|
test: ["CMD-SHELL", "pg_isready -U postgres -d danyang_match"]
|
|
|
|
|
|
interval: 10s
|
|
|
|
|
|
timeout: 5s
|
|
|
|
|
|
retries: 5
|
|
|
|
|
|
|
|
|
|
|
|
redis:
|
|
|
|
|
|
image: redis:7-alpine
|
|
|
|
|
|
container_name: danyang-match-redis
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "6381:6379"
|
|
|
|
|
|
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD:?请在本地 .env 设置 REDIS_PASSWORD}
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- redis_data:/data
|
|
|
|
|
|
healthcheck:
|
|
|
|
|
|
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:?请在本地 .env 设置 REDIS_PASSWORD}", "ping"]
|
|
|
|
|
|
interval: 10s
|
|
|
|
|
|
timeout: 5s
|
|
|
|
|
|
retries: 5
|
|
|
|
|
|
|
|
|
|
|
|
minio:
|
2026-09-18 21:58:56 +08:00
|
|
|
|
# pin 到确定版本:`latest` 是滚动 tag,MinIO 已多次改动镜像内容(如移除内嵌 console),
|
|
|
|
|
|
# 用 `latest` 会让 CI 的 E2E 拉到一个与本地验证时不同的镜像 → 不可复现的偶发失败。
|
|
|
|
|
|
image: minio/minio:RELEASE.2025-09-07T16-13-09Z
|
2026-09-10 10:58:43 +08:00
|
|
|
|
container_name: danyang-match-minio
|
|
|
|
|
|
command: server /data --console-address ":9001"
|
|
|
|
|
|
environment:
|
|
|
|
|
|
MINIO_ROOT_USER: ${MINIO_ACCESS_KEY:?请在本地 .env 设置 MINIO_ACCESS_KEY}
|
|
|
|
|
|
MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY:?请在本地 .env 设置 MINIO_SECRET_KEY}
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "9003:9000"
|
|
|
|
|
|
- "9004:9001"
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
- minio_data:/data
|
|
|
|
|
|
healthcheck:
|
|
|
|
|
|
test: ["CMD", "mc", "ready", "local"]
|
|
|
|
|
|
interval: 10s
|
|
|
|
|
|
timeout: 5s
|
|
|
|
|
|
retries: 5
|
|
|
|
|
|
|
|
|
|
|
|
backend:
|
|
|
|
|
|
build:
|
|
|
|
|
|
context: ../backend
|
|
|
|
|
|
dockerfile: Dockerfile
|
|
|
|
|
|
container_name: danyang-match-backend
|
|
|
|
|
|
depends_on:
|
|
|
|
|
|
postgres:
|
|
|
|
|
|
condition: service_healthy
|
|
|
|
|
|
redis:
|
|
|
|
|
|
condition: service_healthy
|
|
|
|
|
|
minio:
|
|
|
|
|
|
condition: service_healthy
|
|
|
|
|
|
environment:
|
|
|
|
|
|
SPRING_PROFILES_ACTIVE: docker
|
|
|
|
|
|
DB_HOST: postgres
|
|
|
|
|
|
DB_PORT: 5432
|
|
|
|
|
|
DB_NAME: danyang_match
|
|
|
|
|
|
DB_USER: postgres
|
|
|
|
|
|
DB_PASSWORD: ${DB_PASSWORD:?请在本地 .env 设置 DB_PASSWORD}
|
|
|
|
|
|
REDIS_HOST: redis
|
|
|
|
|
|
REDIS_PORT: 6379
|
|
|
|
|
|
REDIS_PASSWORD: ${REDIS_PASSWORD:?请在本地 .env 设置 REDIS_PASSWORD}
|
|
|
|
|
|
MINIO_ENDPOINT: http://minio:9000
|
|
|
|
|
|
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:?请在本地 .env 设置 MINIO_ACCESS_KEY}
|
|
|
|
|
|
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:?请在本地 .env 设置 MINIO_SECRET_KEY}
|
|
|
|
|
|
JWT_ACCESS_SECRET: ${JWT_ACCESS_SECRET:?请在本地 .env 设置 JWT_ACCESS_SECRET}
|
|
|
|
|
|
JWT_REFRESH_SECRET: ${JWT_REFRESH_SECRET:?请在本地 .env 设置 JWT_REFRESH_SECRET}
|
|
|
|
|
|
ENCRYPTION_KEY: ${ENCRYPTION_KEY:?请在本地 .env 设置 ENCRYPTION_KEY}
|
|
|
|
|
|
WECHAT_APP_ID: dev-wechat-app-id
|
|
|
|
|
|
WECHAT_APP_SECRET: ${WECHAT_APP_SECRET:-}
|
|
|
|
|
|
ports:
|
|
|
|
|
|
- "8085:8080"
|
|
|
|
|
|
healthcheck:
|
2026-09-18 22:27:26 +08:00
|
|
|
|
# 与 nginx 同理,用 127.0.0.1 而非 localhost:backend 当前恰好双栈监听(:::8080),
|
|
|
|
|
|
# 故 localhost 解析成 ::1 也能通;但探针不应依赖「服务恰好绑了 IPv6」这一偶然事实。
|
|
|
|
|
|
test: ["CMD-SHELL", "wget -qO /dev/null http://127.0.0.1:8080/api/v1/health/live || exit 1"]
|
2026-09-10 10:58:43 +08:00
|
|
|
|
interval: 30s
|
|
|
|
|
|
timeout: 10s
|
|
|
|
|
|
retries: 3
|
|
|
|
|
|
|
2026-09-14 10:02:34 +08:00
|
|
|
|
admin-web:
|
|
|
|
|
|
build:
|
|
|
|
|
|
context: ../admin-web
|
|
|
|
|
|
dockerfile: Dockerfile
|
|
|
|
|
|
container_name: danyang-match-admin
|
|
|
|
|
|
depends_on:
|
|
|
|
|
|
backend:
|
|
|
|
|
|
condition: service_healthy
|
|
|
|
|
|
|
2026-09-10 10:58:43 +08:00
|
|
|
|
nginx:
|
|
|
|
|
|
image: nginx:alpine
|
|
|
|
|
|
container_name: danyang-match-nginx
|
|
|
|
|
|
depends_on:
|
2026-09-14 10:02:34 +08:00
|
|
|
|
backend:
|
|
|
|
|
|
condition: service_healthy
|
|
|
|
|
|
admin-web:
|
|
|
|
|
|
condition: service_started
|
2026-09-10 10:58:43 +08:00
|
|
|
|
ports:
|
2026-09-14 10:02:34 +08:00
|
|
|
|
- "6688:80"
|
2026-09-10 10:58:43 +08:00
|
|
|
|
volumes:
|
|
|
|
|
|
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
|
|
|
|
|
healthcheck:
|
2026-09-18 22:27:26 +08:00
|
|
|
|
# 探针地址必须写 127.0.0.1,不能写 localhost。
|
|
|
|
|
|
# 实测:nginx 的 `listen 80` 只绑 IPv4(容器内 netstat = 0.0.0.0:80),
|
|
|
|
|
|
# 而 /etc/hosts 中 `::1 localhost` 同样存在,busybox wget 解析 localhost 时优先取 ::1
|
|
|
|
|
|
# → 探针连 IPv6 回环被拒(Connection refused)→ 容器被标 unhealthy,
|
|
|
|
|
|
# 但服务其实完全正常(宿主 curl http://localhost:6688/nginx-health = 200)。
|
|
|
|
|
|
# 这是一类「探针与被探对象脱钩」的假告警,还会连带拖垮 depends_on: service_healthy。
|
|
|
|
|
|
test: ["CMD-SHELL", "wget -qO /dev/null http://127.0.0.1/nginx-health || exit 1"]
|
2026-09-10 10:58:43 +08:00
|
|
|
|
interval: 30s
|
|
|
|
|
|
timeout: 10s
|
|
|
|
|
|
retries: 3
|
|
|
|
|
|
|
|
|
|
|
|
volumes:
|
|
|
|
|
|
postgres_data:
|
|
|
|
|
|
redis_data:
|
|
|
|
|
|
minio_data:
|