Dockernetworking – nginx:主机在上游找不到

我最近开始迁移到Docker 1.9和Docker-Compose 1.5的networkingfunction来replace使用链接。

到目前为止,通过docker-compose连接到位于不同服务器的php5-fpm fastcgi服务器,nginx没有任何问题。 虽然当我运行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容器运行时(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 

这是我的nginx的default.conf

 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调用?

有可能使用“volumes_from”作为解决方法,直到引入了depends_onfunction(下面讨论)。 所有你需要做的就是改变你的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_onfunction这可能是一个未来的答案。 由于该function尚未在Docker中实现(从1.9开始)

有个build议在Docker引入的新networkingfunction中引入“depends_on”。 但是关于同样的@ https://github.com/docker/compose/issues/374有一个长时间的争论。因此,一旦它被实现,可以使用depends_on命令来命令容器启动,但是在一刻,你将不得不诉诸以下之一:;

  1. 让nginx重试,直到php服务器启动 – 我宁愿这一个
  2. 使用volums_from上述的解决方法 – 我会避免使用这个,因为体积泄漏到不必要的容器。

这可以通过提到的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 

成功通过以下testing:

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

在文档中find更多详细信息。

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

我相信Nginx不考虑Dockerparsing器(127.0.0.11),所以,请你尝试添加:

 resolver 127.0.0.11 

在你的nginxconfiguration文件中?

您可以设置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秒。

准确地说,你修改过的nginxconfiguration文件应该如下(这个脚本假定所有的容器至less加了25秒,如果没有的话,请在下面的上游部分更改fail_timeout或max_fails):注意:我没有我自己testing脚本,所以你可以试试看!

 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; } } 

此外,根据docker( https://github.com/docker/compose/blob/master/docs/networking.md )的以下注释,显然检查其他容器的健康的重试逻辑不是docker的责任,而是容器应该自己做健康检查。

更新容器

如果您对服务进行configuration更改,然后运行docker-compose进行更新,则旧容器将被删除,新的容器将以不同的IP地址joinnetworking,但名称相同。 正在运行的容器将能够查找该名称并连接到新地址,但旧地址将停止工作。

如果有任何容器连接到旧容器,它们将被closures。 检测这种情况是一个容器的责任,再次查找名称并重新连接。

通过链接,可以执行容器启动顺序。 没有链接,容器可以以任何顺序启动(或者一次全部启动)。

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

我想要得到它的工作,你可以创build一个nginx入口点脚本,轮询和等待PHP容器启动和准备。

我不确定nginx是否有办法自动重新尝试连接到上游,但是如果是这样,这将是一个更好的select。

当你的后端启动时,你必须使用像docker-gen这样的dynamic更新nginxconfiguration。

看到:

我相信Nginx +(高级版本)也包含parsing参数( http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream

也许避免链接容器问题的最佳select是dockernetworkingfunction

但为了使这个工作,docker工人在每个容器的分配名称中为每个容器在/ etc / hosts中创build条目。

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 

确保在您的configuration文件中为此服务分配了相同的名称。 我很确定有更好的方法来做到这一点,但这是一个很好的开始。

这是我如何得到它,我能想到的最好的方式。

 ADD root / RUN cp /etc/hosts /etc/hosts.tmp && \ echo -e "\ 127.0.0.1 code_gogs_1 \n\ 127.0.0.1 pm_zentao_1 \n\ 127.0.0.1 ci_drone_1 \n\ " >> /etc/hosts && \ nginx -t && \ # mv: can't rename '/etc/hosts.tmp': Resource busy # mv /etc/hosts.tmp /etc/hosts cat /etc/hosts.tmp > /etc/hosts && \ rm /etc/hosts.tmp 

将链接部分添加到您的nginx容器configuration。

你必须使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