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命令来命令容器启动,但是在一刻,你将不得不诉诸以下之一:;
- 让nginx重试,直到php服务器启动 – 我宁愿这一个
- 使用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