加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 如何让nginx等待我的上游服务在Docker Swarm中

发布时间:2020-12-17 03:33:11 所属栏目:百科 来源:网络整理
导读:我将nginx代理服务和rails应用服务部署到docker swarm中. nginx依赖于我的docker-compose文件中的应用程序. 我的nginx.conf文件将流量定向到我的上游应用服务(在端口3000上公开),如此(仅显示上游部分). upstream puma { server app:3000;} 我的docker-compos
我将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文件中有一个depends部分 – 在nginx服务启动时,app服务可能还没有完全准备好(?),所以当上游服务配置部分尝试DNS解析“app: 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启动时它还无法正确解析我的swarm服务app:3000 – 而是试图将流量传递到一个IP地址….

顺便说一句 – 如果我重新启动我的虚拟机也会出现同样的情况 – 当docker(在swarm模式下)再次启动服务时 – 我最终会遇到同样的问题.重新启动nginx容器可以解决问题.

解决方法

我找到了一种方法 – 这是使用Dockerfile的HEALTHCHECK部分或docker-compose文件.

首先,似乎在部署堆栈时没有真正使用depends_on选项

docker stack deploy -c docker-compose.yml mystack

如果无法正常启动或因某些其他原因失败,则群集模式下的Docker将重新启动服务任务.所以depends_on选项并没有那么有用.

所以这是我的解决方案,到目前为止它的效果非常好:

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"
    networks:
      - proxy
    healthcheck:
        test: ["CMD","wget","-qO-","http://localhost/healthcheck"]
        interval: 5s
        timeout: 3s
        retries: 3

networks:

  proxy:
    external: true

所以我所做的是,从nginx服务器上我尝试在我的Rails应用程序上访问一个路由 – 我创建了一个名为/ healthcheck并返回状态代码200.

因此,当我尝试访问它时,结果是失败(应用程序服务器还没有准备好) – 将重新启动nginx.希望当它再次启动时,应用程序服务器将可用,并且上游app:3000指令将执行正确的DNS解析.

因此,通过这种方式,我已经“破解”了可以在群模式下工作的(缺失的)depends_on行为.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读