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


98

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

到目前为止,nginx通过docker-compose连接到我的php5-fpm fastcgi服务器是没有问题的,该服务器位于一组中的另一台服务器中。最近,尽管当我运行docker-compose --x-networking upphp-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容器(退出nginx)时再次运行docker-compose命令,则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

这是我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;
    }
}

我如何才能使nginx仅与单个docker-compose调用一起使用?


3
我也遇到了这个。我不确定这是撰写文件错误还是docker网络本身的错误。
2015年

Answers:


26

在引入depends_on功能(在下面讨论)之前,可以使用“ volumes_from”作为解决方法。您要做的就是如下更改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

上述方法的一个重要警告是,php的体积暴露于nginx,这是不希望的。但是目前,这是可以使用的一种特定于docker的解决方法。

depends_on功能 这可能是一个未来派的答案。因为该功能尚未在Docker中实现(从1.9版本开始)

有建议在Docker引入的新网络功能中引入“ depends_on”。但是关于相同的@ https://github.com/docker/compose/issues/374一直存在着长期争论,因此,一旦实现,就可以使用depends_on功能来命令启动容器,但是在此刻,您将不得不采取以下措施之一:

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

3
这并不能解决我的问题。
Gijs

@Gijs如果您可以发布您的确切情况是什么,什么不起作用,则可以在论坛上提供帮助。
帕尼

4
volume_from已弃用
Roma Rush

我在Azure App Service Docker Compose(预览版)中遇到了一个问题。还必须确保links:在nginx中包含的所有 名称都使用与- my-service:my-service示例本身相同的名称,与服务本身相同- mongo:mongo
greg

28

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

已成功测试:

$ docker-compose version
docker-compose version 1.8.0, build f3628c7

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

还有一篇非常有趣的文章专门针对此主题:在Compose中控制启动顺序


12

您可以设置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 {
   server 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;
    }
}

此外,根据docker的以下说明(https://github.com/docker/docker.github.io/blob/master/compose/networking.md#update-containers),很明显,用于检查的重试逻辑其他容器的健康状况不是码头工人的责任,而是这些容器应自行进行健康检查。

更新容器

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

如果有任何容器与旧容器打开了连接,则它们将被关闭。检测这种情况,再次查找名称并重新连接是容器的责任。


3
这行不通。请阅读Nginx文档本节末尾的警告:“如果组中只有一台服务器,则max_fails,fail_timeout和slow_start参数将被忽略,这样的服务器将永远不会被视为不可用。”
Ferguzz

1
@Ferguzz很不错。解决方法是,您可以添加同一容器的两个别名条目,以使同一容器中的组成为一组。

作为替代解决方案,我在同一问题中提供了使用“ volumes_from”链接容器并使它们等到其他容器被加载的方法。这对我有用。

7

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

resolver 127.0.0.11

在您的nginx配置文件中?


添加多个解析器,例如resolver 127.0.0.11 8.8.8.8;
Leonardo Chaia

1
否,因为它将按照docs中所述以循环方式查询:名称服务器以循环方式查询。
达洛尔

6

如果您迷失了阅读最后的评论。我已经找到另一种解决方案。

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

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


3

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


这远远不是答案。
dargmuesli

2

遇到了同样的问题并解决了。请将以下行添加到docker-compose.yml nginx部分:

links:
  - php:waapi_php_1

应该在docker-compose.yml nginx配置内链接nginx config fastcgi_pass部分中的主机。


1

值得一提的两件事:

  • 使用相同的网桥
  • 使用links添加主机甲阶酚醛

我的例子:

version: '3'
services:
  mysql:
    image: mysql:5.7
    restart: always
    container_name: mysql
    volumes:
      - ./mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: tima@123
    network_mode: bridge
  ghost:
    image: ghost:2
    restart: always
    container_name: ghost
    depends_on:
      - mysql
    links:
      - mysql
    environment:
      database__client: mysql
      database__connection__host: mysql
      database__connection__user: root
      database__connection__password: xxxxxxxxx
      database__connection__database: ghost
      url: https://www.itsfun.tk
    volumes:
      - ./ghost-data:/var/lib/ghost/content
    network_mode: bridge
  nginx:
    image: nginx
    restart: always
    container_name: nginx
    depends_on:
      - ghost
    links:
      - ghost
    ports:
      - "80:80"
      - "443:443"
    volumes:
       - ./nginx/nginx.conf:/etc/nginx/nginx.conf
       - ./nginx/conf.d:/etc/nginx/conf.d
       - ./nginx/letsencrypt:/etc/letsencrypt
    network_mode: bridge

如果未指定特殊的网桥,则所有网桥都将使用相同的默认网桥。


1

乍一看,我错过了我的“ Web”服务实际上没有启动的原因,因此这就是nginx找不到任何主机的原因

web_1    | python3: can't open file '/var/www/app/app/app.py': [Errno 2] No such file or directory
web_1 exited with code 2
nginx_1  | [emerg] 1#1: host not found in upstream "web:4044" in /etc/nginx/conf.d/nginx.conf:2

嘿,我有同样的问题。我的应用程序未运行,因此出现了同样的错误。我将uwsgi-file作为run.py放入了app.ini中,该文件本来可以运行该应用程序,但未发生
isrj5

0

通过链接,可以强制执行容器启动的顺序。如果没有链接,则容器可以按任何顺序启动(或实际上一次启动)。

我认为,如果waapi_php_1容器启动缓慢,旧的设置可能会遇到相同的问题。

我认为要使其正常工作,您可以创建一个nginx入口点脚本,该脚本轮询并等待php容器启动并准备就绪。

我不确定nginx是否可以自动重试与上游的连接,但是如果这样做,那将是一个更好的选择。


以及我如何进行轮询?
Attila Szeremi 2015年


0

也许避免链接容器问题的最佳选择是Docker网络功能

但是要使此工作有效,docker在/ etc / hosts中为每个容器从分配的名称到每个容器创建条目。

使用docker-compose --x-networking -up类似于[docker_compose_folder]-[service]-[incremental_number]

为了不依赖这些名称的意外更改,应使用参数

container_name

在您的docker-compose.yml中,如下所示:

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

确保它与在此服务的配置文件中分配的名称相同。我敢肯定,有更好的方法可以做到这一点,但这是一个很好的起点。


0

我的解决方法(经过多次尝试和错误):

  • 为了解决这个问题,我必须获得“上游” Docker容器的全名,可以通过运行docker network inspect my-special-docker-network并获取name上游容器的full属性来找到它:

    "Containers": {
         "39ad8199184f34585b556d7480dd47de965bc7b38ac03fc0746992f39afac338": {
              "Name": "my_upstream_container_name_1_2478f2b3aca0",
    
  • 然后在属性块的NGINXmy-network.local.conf文件中使用它:(注意,在容器名称中添加了GUID):locationproxy_pass

    location / {
        proxy_pass http://my_upsteam_container_name_1_2478f2b3aca0:3000;
    

与以前的工作方式相反,但现在已中断:

    location / {
        proxy_pass http://my_upstream_container_name_1:3000

最可能的原因是近期变化多克尔撰写,在容器的默认命名方案,为上市这里

对于我和我的团队,这似乎正在发生,使用最新版本的Dockernginx映像:

  • 我在泊坞窗打开他们的问题/撰写的GitHub这里

0

(对nginx来说是新的)对于我来说,这是错误的文件夹名称

对于配置

upstream serv {
    server ex2_app_1:3000;
}

确保app文件夹位于ex2文件夹中:

ex2 / app / ...


0

我出现此错误是因为php-fpm启用了我的图片cron,我也不知道为什么


0

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

    networks:
      - u-online

很好!

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

-1

链接部分添加到您的nginx容器配置中。

您必须使php容器对nginx容器可见。

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

1
我知道链接,但是Docker在一周前发布的1.9版本中将其标记为不推荐使用,以支持使用Docker的网络。我想要一个使用该解决方案的解决方案,部分原因是链接存在网络不应该存在的循环链接问题。
Attila Szeremi 2015年

1
CHANGELOG.md中,我看不到link被弃用。我想念什么吗?
nessuno 2015年

我也没有在那里看到。但是,当我docker-compose --x-networking up使用在自己的链接中定义的链接运行时docker-compose.yml,会收到以下明确警告:WARNING: "nginx" defines links, which are not compatible with Docker networking and will be ignored. Future versions of Docker will not support links - you should remove them for forwards-compatibility.
Attila Szeremi 2015年

好的,我发现过时了。我唯一的想法是:您是否将docker-compose.yml文件存储在名为的文件夹中waapi
nessuno 2015年

是的,它在一个名为waapi
Attila Szeremi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.