# Production Docker Compose # 生产环境配置,敏感信息通过 .env 文件注入,不进 Git services: postgres: image: postgres:16-alpine container_name: danyang-match-postgres environment: POSTGRES_DB: ${DB_NAME:-danyang_match} POSTGRES_USER: ${DB_USER:-danyang} POSTGRES_PASSWORD_FILE: /run/secrets/db_password ports: - "127.0.0.1:5432:5432" volumes: - postgres_data:/var/lib/postgresql/data - ./backups:/backups healthcheck: test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-danyang} -d ${DB_NAME:-danyang_match}"] interval: 10s timeout: 5s retries: 5 networks: - danyang-net secrets: - db_password restart: unless-stopped redis: image: redis:7-alpine container_name: danyang-match-redis command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD:?请设置REDIS_PASSWORD} volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:?请设置REDIS_PASSWORD}", "ping"] interval: 10s timeout: 5s retries: 5 networks: - danyang-net restart: unless-stopped seaweedfs: # 同 docker-compose.yml:对象存储已从 MinIO 换成 SeaweedFS。 # 生产换的动力比 CI 更强 —— MinIO 仓库已归档、不再产出安全补丁, # 而这里存的是身份证与实名材料。详见 docker-compose.yml 中的完整说明。 # 版本与本地/CI 一致(钉 4.47),避免各环境跑不同实现。 image: chrislusf/seaweedfs:4.47 container_name: danyang-match-seaweedfs # 必须覆盖 entrypoint:镜像 ENTRYPOINT 是 /usr/bin/weed,只写 command 会被追加成 # `weed sh -c ...` → `weed: unknown subcommand "sh"`(本地实测踩到)。 entrypoint: ["sh", "-c"] command: - | cat > /tmp/s3cfg.json < $$code" done networks: - danyang-net restart: "no" backend: build: context: ../backend dockerfile: Dockerfile container_name: danyang-match-backend depends_on: postgres: condition: service_healthy redis: condition: service_healthy seaweedfs: condition: service_healthy storage-init: condition: service_completed_successfully environment: SPRING_PROFILES_ACTIVE: docker,production SPRING_CONFIG_IMPORT: configtree:/run/secrets/ DB_HOST: postgres DB_PORT: 5432 DB_NAME: ${DB_NAME:-danyang_match} DB_USER: ${DB_USER:-danyang} REDIS_HOST: redis REDIS_PORT: 6379 REDIS_PASSWORD: ${REDIS_PASSWORD:?请设置REDIS_PASSWORD} # 变量名仍为 MINIO_*(服务端配置键未改),实际指向 SeaweedFS 的 S3 网关。 MINIO_ENDPOINT: http://seaweedfs:8333 # 客户端直传 presigned URL 用的「对外可达」地址。 # 生产 S3 网关当前未 host-publish(客户端经 nginx/ingress 访问),故缺省仍是容器名 # —— 即「presigned host 对外可达」缺陷在生产仍待配置 ingress 后才彻底解决。 # 一旦生产 S3 网关暴露了对外地址,把该变量设成那个地址即可,无需再改代码。 MINIO_PUBLIC_ENDPOINT: ${MINIO_PUBLIC_ENDPOINT:http://seaweedfs:8333} MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:?请设置MINIO_ACCESS_KEY} MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:?请设置MINIO_SECRET_KEY} JWT_ACCESS_SECRET: ${JWT_ACCESS_SECRET:?请设置JWT_ACCESS_SECRET} JWT_REFRESH_SECRET: ${JWT_REFRESH_SECRET:?请设置JWT_REFRESH_SECRET} CHECKIN_TOKEN_SECRET: ${CHECKIN_TOKEN_SECRET:?请设置CHECKIN_TOKEN_SECRET} ENCRYPTION_KEY: ${ENCRYPTION_KEY:?请设置ENCRYPTION_KEY} WECHAT_APP_ID: ${WECHAT_APP_ID:?请设置WECHAT_APP_ID} WECHAT_APP_SECRET: ${WECHAT_APP_SECRET:?请设置WECHAT_APP_SECRET} VERIFICATION_PROVIDER: ${VERIFICATION_PROVIDER:?请设置VERIFICATION_PROVIDER} SPRING_SECURITY_FALLBACK_PASSWORD: ${SPRING_SECURITY_FALLBACK_PASSWORD:?请设置SPRING_SECURITY_FALLBACK_PASSWORD} FEATURES_APPEAL_ENABLED: ${FEATURES_APPEAL_ENABLED:-false} ports: - "127.0.0.1:8080:8080" networks: - danyang-net secrets: - source: db_password target: spring.datasource.password restart: unless-stopped deploy: resources: limits: memory: 512M reservations: memory: 256M admin-web: build: context: ../admin-web dockerfile: Dockerfile container_name: danyang-match-admin depends_on: - backend ports: # 管理端端口统一 13520(与 admin-web/vite.config.ts 的开发端口一致, # 由 ui-tests/ui-document-baseline-contracts.mjs 钉住三处一致)。 # 仍绑定 127.0.0.1:对外访问走 nginx 的 80/443 + /admin/,此处仅供本机直连排查。 - "127.0.0.1:13520:80" networks: - danyang-net restart: unless-stopped nginx: image: nginx:alpine container_name: danyang-match-nginx depends_on: - backend - admin-web ports: - "80:80" - "443:443" volumes: - ./nginx-production.conf:/etc/nginx/nginx.conf:ro - ./certs:/etc/nginx/certs:ro networks: - danyang-net restart: unless-stopped volumes: postgres_data: redis_data: seaweedfs_data: networks: danyang-net: driver: bridge secrets: db_password: file: ./secrets/db_password.txt