Docker Networking - nginx:[emerg]主机在上游找不到

Att*_*emi 74 nginx docker docker-compose docker-networking

我最近开始迁移到Docker 1.9和Docker-Compose 1.5的网络功能,以替换使用链接.

到目前为止链接没有问题nginx通过docker-compose连接到位于一组不同服务器中的php5-fpm fastcgi服务器.最近,当我运行docker-compose --x-networking up我的php-fpm时,mongo和nginx容器启动,但nginx立即退出[emerg] 1#1: host not found in upstream "waapi_php_1" in /etc/nginx/conf.d/default.conf:16

但是,如果我在php和mongo容器运行时再次运行docker-compose命令(nginx退出),nginx启动并从那时起正常工作.

这是我的docker-compose.yml档案:

nginx:
  image: nginx
  ports:
    - "42080:80"
  volumes:
    - ./config/docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro

php:
  build: config/docker/php
  ports:
    - "42022:22"
  volumes:
    - .:/var/www/html
  env_file: config/docker/php/.env.development

mongo:
  image: mongo
  ports:
    - "42017:27017"
  volumes:
    - /var/mongodata/wa-api:/data/db
  command: --smallfiles
Run Code Online (Sandbox Code Playgroud)

这是我default.conf的nginx:

server {
    listen  80;

    root /var/www/test;

    error_log /dev/stdout debug;
    access_log /dev/stdout;

    location / {
        # try to serve file directly, fallback to app.php
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/.+\.php(/|$) {
        # Referencing the php service host (Docker)
        fastcgi_pass waapi_php_1:9000;

        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;

        # We must reference the document_root of the external server ourselves here.
        fastcgi_param SCRIPT_FILENAME /var/www/html/public$fastcgi_script_name;

        fastcgi_param HTTPS off;
    }
}
Run Code Online (Sandbox Code Playgroud)

如何让nginx只使用一个docker-compose调用?

Pha*_*ani 21

有可能使用"volumes_from"作为解决方法,直到引入了depends_on功能(下面讨论).您所要做的就是更改docker-compose文件,如下所示:

nginx:
  image: nginx
  ports:
    - "42080:80"
  volumes:
    - ./config/docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
  volumes_from:
    - php

php:
  build: config/docker/php
  ports:
    - "42022:22"
  volumes:
    - .:/var/www/html
  env_file: config/docker/php/.env.development

mongo:
  image: mongo
  ports:
    - "42017:27017"
  volumes:
    - /var/mongodata/wa-api:/data/db
  command: --smallfiles
Run Code Online (Sandbox Code Playgroud)

上述方法的一个重要注意事项是php的体积暴露给nginx,这是不可取的.但目前这是一个可以使用的特定于docker的解决方法.

depends_on feature 这可能是一个未来主义的答案.因为Docker中尚未实现该功能(截至1.9)

有人建议在Docker引入的新网络功能中引入"depends_on".但是有一个长期存在争论的问题@ https://github.com/docker/compose/issues/374因此,一旦实现,功能depends_on可用于订购容器启动,但在那一刻,你将不得不诉诸下列之一:

  1. 让nginx重试,直到php服务器启动 - 我更喜欢这个
  2. 如上所述使用volums_from解决方法 - 我会避免使用它,因为卷泄漏到不必要的容器中.

  • 不推荐使用volumes_from (5认同)
  • 这对我没有解决. (3认同)

cze*_*asz 19

这可以通过上述depends_on指令解决,因为它现在已经实施(2016):

version: '2'
  services:
    nginx:
      image: nginx
      ports:
        - "42080:80"
      volumes:
        - ./config/docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
      depends_on:
        - php

    php:
      build: config/docker/php
      ports:
        - "42022:22"
      volumes:
        - .:/var/www/html
      env_file: config/docker/php/.env.development
      depends_on:
        - mongo

    mongo:
      image: mongo
      ports:
        - "42017:27017"
      volumes:
        - /var/mongodata/wa-api:/data/db
      command: --smallfiles
Run Code Online (Sandbox Code Playgroud)

成功测试:

$ docker-compose version
docker-compose version 1.8.0, build f3628c7
Run Code Online (Sandbox Code Playgroud)

文档中查找更多详细信息.

还有一篇非常有趣的文章专门讨论这个主题:在Compose中控制启动顺序


Pha*_*ani 10

您可以设置nginx的max_fails和fail_timeout指令,以指示在上游服务器不可用失败之前,nginx应重试对容器的x个连接请求.

您可以根据您的基础架构和整个设置即将到来的速度来调整这两个数字.您可以阅读以下URL的健康检查部分的更多详细信息:http: //nginx.org/en/docs/http/load_balancing.html

以下是http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server的摘录 max_fails=number

设置在fail_timeout参数设置的持续时间内发生的与服务器通信的不成功尝试次数,以考虑服务器在fail_timeout参数设置的持续时间内不可用.默认情况下,不成功尝试次数设置为1.零值禁用尝试的计费.被认为是不成功的尝试由proxy_next_upstream,fastcgi_next_upstream,uwsgi_next_upstream,scgi_next_upstream和memcached_next_upstream指令定义.

fail_timeout=time

设置指定数量的不成功尝试与服务器通信的时间,以考虑服务器不可用; 以及服务器被视为不可用的时间段.默认情况下,参数设置为10秒.

准确地说,您修改后的nginx配置文件应如下所示(此脚本假设所有容器至少上升25秒,如果没有,请更改下游上游部分中的fail_timeout或max_fails):注意:我没有我自己测试脚本,所以你可以尝试一下!

upstream phpupstream {
   waapi_php_1:9000 fail_timeout=5s max_fails=5;
}
server {
    listen  80;

    root /var/www/test;

    error_log /dev/stdout debug;
    access_log /dev/stdout;

    location / {
        # try to serve file directly, fallback to app.php
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/.+\.php(/|$) {
        # Referencing the php service host (Docker)
        fastcgi_pass phpupstream;

        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;

        # We must reference the document_root of the external server ourselves here.
        fastcgi_param SCRIPT_FILENAME /var/www/html/public$fastcgi_script_name;

        fastcgi_param HTTPS off;
    }
}
Run Code Online (Sandbox Code Playgroud)

另外,根据docker的以下注释(https://github.com/docker/compose/blob/master/docs/networking.md),显然用于检查其他容器的运行状况的重试逻辑不是码头工人的责任,而容器应该自己做健康检查.

更新容器

如果您对服务进行配置更改并运行docker-compose以更新它,则旧容器将被删除,新容器将以不同的IP地址但名称相同的方式加入网络.运行容器将能够查找该名称并连接到新地址,但旧地址将停止工作.

如果任何容器的连接打开旧容器,它们将被关闭.容器有责任检测此情况,再次查找名称并重新连接.

  • 这行不通。请阅读Nginx文档本节末尾的警告:“如果组中只有一台服务器,则将忽略max_fails,fail_timeout和slow_start参数,并且永远不会认为该服务器不可用。” (2认同)

*_*лов 10

我的问题是我忘记在php-fpm的 docker-compose.yml 中指定网络别名

    networks:
      - u-online
Run Code Online (Sandbox Code Playgroud)

效果很好!

version: "3"
services:

  php-fpm:
    image: php:7.2-fpm
    container_name: php-fpm
    volumes:           
      - ./src:/var/www/basic/public_html
    ports:
      - 9000:9000
    networks:
      - u-online
      
  nginx: 
    image: nginx:1.19.2
    container_name: nginx   
    depends_on:
      - php-fpm       
    ports:
      - "80:8080"
      - "443:443"
    volumes:
      - ./docker/data/etc/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
      - ./docker/data/etc/nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./src:/var/www/basic/public_html
    networks:
      - u-online

#Docker Networks
networks:
  u-online:
    driver: bridge
Run Code Online (Sandbox Code Playgroud)


小智 9

如果您对阅读最后一条评论感到迷茫。我已经达到了另一个解决方案。

主要问题是您命名服务名称的方式。

在这种情况下,如果在您docker-compose.yml的 php 服务中称为“api”或类似名称,您必须确保文件中nginx.conf以 开头的行与fastcgi_passphp 服务具有相同的名称。IEfastcgi_pass api:9000;


Tho*_*aux 7

我相信Nginx不会考虑Docker解析器(127.0.0.11),所以请您尝试添加:

resolver 127.0.0.11
Run Code Online (Sandbox Code Playgroud)

在您的nginx配置文件中?


小智 5

我遇到了同样的问题,因为在我的文件中定义了两个网络docker-compose.yml:一个后端和一个前端。
当我将其更改为在同一默认网络上运行容器时,一切都开始正常工作。