Docker:proxy_pass 到另一个容器 - nginx:在上游找不到主机

Posted

技术标签:

【中文标题】Docker:proxy_pass 到另一个容器 - nginx:在上游找不到主机【英文标题】:Docker: proxy_pass to another container - nginx: host not found in upstream 【发布时间】:2018-01-24 20:22:46 【问题描述】:

(我知道其他人之前已经问过这个问题,但我无法使用其他帖子中提出的解决方案来解决问题,所以我想我会尝试发布我的配置文件,看看是否有人可以帮助。)

我想为 nginx 创建一个容器,并使用proxy_pass 将请求传递给正在运行的 Web 应用程序的容器。我不知道如何在两个容器之间进行通信。当我尝试运行 docker stack deploy -c docker-compose.yml somename 时,只有 Web 容器启动。 nginx容器启动失败,卡在尝试重启的循环中。这是我收到的日志消息:

2017/08/16 14:56:10 [emerg] 1#1:在上游“web:8000”中找不到主机 在 /etc/nginx/conf.d/nginx.conf:2 nginx: [emerg] 找不到主机 /etc/nginx/conf.d/nginx.conf:2 中的上游“web:8000”

我找到了一个答案,只要你在docker-compose.yml文件中使用与服务下相同的名称,nginx就会找到该变量。但是,这对我来说似乎没有帮助。

不同容器之间的这种通信是如何工作的? 'web' 变量在哪里

我看到的大多数示例在docker-compose.yml 文件中使用version: "2",这会有所不同吗?

我的 docker-compose.yml:

version: "3"
services:
  web:
    image: user/repo:web
    deploy:
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "8000:80"
    networks:
      - webnet

  nginx:
    image: user/repo:nginx
    ports:
      - 80:80
    links:
      - web:web
    depends_on:
      - web

networks:
  webnet:

Nginx 配置:

upstream docker-web 
    server web:8000;



server 
    listen 80;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location / 
         proxy_pass http://docker-web;

         proxy_set_header   Host $host;
         proxy_set_header   X-Real-IP $remote_addr;
         proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header   X-Forwarded-Host $server_name;
    

【问题讨论】:

【参考方案1】:

您好,您的问题是链接 web:web 时的端口,您需要指定容器运行服务的端口,例如

    ports:
  - "8000:80"

表示容器内部我可以通过端口 80 访问,但在主机中我可以通过 8000 访问。 这是doc 关于在 docker-compose 中链接两个服务的内容

所以如果你想在代理 nginx 中访问网络,请不要使用 8000 但使用:

upstream docker-web 
server web:80;
  

相反,这应该可行:)

或(两者相同)

 upstream docker-web 
    server web;
      

【讨论】:

【参考方案2】:

这很简单。只需更改旧配置:

upstream docker-web 
    server web:8000;

致这个新的:

upstream docker-web 
    server web:80;

原因是,容器之间无法与发布的端口通信。它只是可以与目标端口通信。 8000:80(8000为发布端口,80为目标端口)。

假设你有 8000:443,你必须在 Nginx 中使用“server web:443”创建配置,监听 443 端口号。愿这有帮助。

【讨论】:

这两天我一直在敲我的脑袋。在 Windows 上的 Docker Desktop 上,这不是它的工作方式。我会映射到 web:8000。然而,在我的 Linux/Ubuntu 机器上,这就是它的工作原理,你映射到 web:80。【参考方案3】:

我想出了如何解决这个问题。得到了一些帮助来修复docker-compose.yml,所以它看起来像这样:

docker-compose-yml:

version: "3"
services:
  web:
    image: user/repo:web
    deploy:
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "8000:80"
    networks:
        main:
            aliases:
                - web


  nginx:
    image: user/repo:nginx
    ports:
      - 80:80
    links:
      - web:web
    depends_on:
      - web
    networks:
        main:
            aliases:
                - nginx
networks:
  main:

在这之后,nginx 容器实际上运行了,但它仍然无法连接到 web 容器。发现我能够同时使用 curl webcurl web -p 8000 从 nginx 容器内部的 web 获取页面。然后我从这里更改了我的nginx.conf 的上游

upstream docker-web 
    server web:8000;

到这里:

upstream docker-web 
    server web;

【讨论】:

【参考方案4】:

您可以通过编辑您的 /etc/hosts 文件并为您的网络主机添加正确的条目来实现这一点

1.1.1.1 web

显然,您必须将 1.1.1.1 替换为 Web 服务器的真实 IP 地址(我想是私有的)。保存文件并重试。另一种解决方法是在配置中替换:

upstream docker-web 
    server web:8000;

upstream docker-web 
    server web-ip-address:8000;

如果你要第二次,别忘了重启/重新加载 nginx!

【讨论】:

以上是关于Docker:proxy_pass 到另一个容器 - nginx:在上游找不到主机的主要内容,如果未能解决你的问题,请参考以下文章

nginx proxy_pass 到链接的 docker 容器

nginx proxy_pass 到 phpmyadmin docker 容器

带有 nginx 容器的 Docker Gitlab 容器

将带有数据的 Docker 容器克隆到另一个主机

从一个 docker 容器无密码登录到另一个

从一个 Docker 容器记录到另一个