我将一个 nginx 代理服务和一个 rails 应用程序服务部署到一个 docker swarm 中。nginx 依赖于我的 docker-compose 文件中的应用程序。
我的 nginx.conf 文件将流量定向到我的上游应用程序服务(暴露在端口 3000),就像这样(仅显示上游部分)。
upstream puma {
server app:3000;
}
我的 docker-compose 文件如下所示:
version: '3.1'
services:
app:
image: my/rails-app:latest
networks:
- proxy
web:
image: my/nginx:1.11.9-alpine
command: /bin/sh -c "nginx -g 'daemon off;'"
ports:
- "80:80"
depends_on:
- app
networks:
- proxy
networks:
proxy:
external: true
我的主机设置为群管理器。
这一切都很好 - 没有问题。
但是,即使我的 docker-compose 文件中有一个依赖部分 - 到 nginx 服务启动时,应用程序服务可能还没有完全(?)准备好,所以当上游服务配置部分尝试 DNS 解析“应用程序: 3000",似乎没有完全找到它。因此,当我访问我的网站时,我在我的 nginx 日志中发现以下错误消息:
2017/02/13 10:46:07 [error] 8#8: *6 connect() failed (111: Connection refused) while connecting to upstream, client: 10.255.0.3, server: www.mysite.com, request: "GET / HTTP/1.1", upstream: "http://127.0.53.53:3000/", host: "preprod.local"
如果我杀死正在运行 nginx 服务的 docker 容器,然后 swarm 稍后重新安排它并返回,如果我然后访问相同的 URL,它就可以完全正常工作,并且请求成功地向上传递到 app:3000。
我怎样才能防止这种情况发生 - 启动时间有点过时并且在 nginx 启动时它还无法正确解析我的名为 app:3000 的群服务 - 相反它正试图将流量传递到一个IP地址....
顺便说一句 - 如果我重新启动我的虚拟机也会发生同样的情况 - 当 docker(在 swarm 模式下)再次启动服务时 - 我可能会遇到同样的问题。重启 nginx 容器即可解决问题。