修复容器健康检查失败的核心问题:IPv6 vs IPv4 和权限
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Failing after 3m47s

问题诊断(本地运行镜像验证):
1. 服务实际已启动在 3000 端口
2. 从宿主机访问健康检查  成功
3. 容器内部 wget localhost:3000  失败 (Connection refused)
4. 健康检查尝试连接 [::1]:3000 (IPv6),但 Fiber 只监听 IPv4

根本原因:
- wget localhost 优先解析为 IPv6 地址 [::1]
- Fiber 默认监听 0.0.0.0:3000 (仅 IPv4)
- Docker 健康检查失败 → 容器标记 unhealthy → Worker 无法启动

修复内容:
1. Dockerfile.api 健康检查: localhost → 127.0.0.1 (强制 IPv4)
2. docker-compose.prod.yml 健康检查: 同步修改
3. Dockerfile.api: 创建 logs 目录并设置 appuser 权限
4. cmd/api/main.go: OpenAPI 文档路径改为 logs/openapi.yaml
This commit is contained in:
2026-01-20 11:50:28 +08:00
parent 286defb063
commit a80dc1e69d
3 changed files with 7 additions and 4 deletions

View File

@@ -67,15 +67,18 @@ COPY migrations /app/migrations
COPY docker/entrypoint-api.sh /app/entrypoint.sh COPY docker/entrypoint-api.sh /app/entrypoint.sh
RUN chmod +x /app/entrypoint.sh RUN chmod +x /app/entrypoint.sh
# 创建日志目录并设置权限(在切换用户前)
RUN mkdir -p /app/logs && chown -R appuser:appuser /app/logs
# 切换到非 root 用户 # 切换到非 root 用户
USER appuser USER appuser
# 暴露端口 # 暴露端口
EXPOSE 3000 EXPOSE 3000
# 健康检查(使用 Alpine 自带的 wget # 健康检查(使用 127.0.0.1 强制 IPv4避免 IPv6 连接问题
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \ HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1 CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:3000/health || exit 1
# 启动命令 # 启动命令
ENTRYPOINT ["/app/entrypoint.sh"] ENTRYPOINT ["/app/entrypoint.sh"]

View File

@@ -81,7 +81,7 @@ func main() {
initRoutes(app, cfg, result, queueClient, db, redisClient, appLogger) initRoutes(app, cfg, result, queueClient, db, redisClient, appLogger)
// 12. 生成 OpenAPI 文档 // 12. 生成 OpenAPI 文档
generateOpenAPIDocs("./openapi.yaml", appLogger) generateOpenAPIDocs("logs/openapi.yaml", appLogger)
// 13. 启动服务器 // 13. 启动服务器
startServer(app, cfg, appLogger, cancelWatch) startServer(app, cfg, appLogger, cancelWatch)

View File

@@ -20,7 +20,7 @@ services:
networks: networks:
- junhong-network - junhong-network
healthcheck: healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health"] test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3000/health"]
interval: 30s interval: 30s
timeout: 3s timeout: 3s
retries: 3 retries: 3