Docker Networking - nginx: [появившийся] хост не найден в восходящем потоке
Недавно я начал переходить на Docker 1.9 и Docker-Compose 1.5 для замены ссылок.
До сих пор со ссылками не возникало проблем с подключением nginx к моему серверу fastcgi php5-fpm, расположенным на другом сервере в одной группе через docker-compose. Но если я запускаю 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
Однако, если я снова запустил команду docker-compose во время работы контейнеров php и mongo (выход 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
Это мой 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 работать только с одним вызовом, связанным с док-станцией?
Ответы
Ответ 1
Существует возможность использовать "volume_from" в качестве обходного пути до тех пор, пока не будет введена функция depend_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
Один большой оговорка в вышеупомянутом подходе заключается в том, что объемы php подвергаются nginx, что нежелательно. Но на данный момент это одно решение для докеры, которое можно использовать.
функция depend_on
Вероятно, это будет футуристический ответ. Поскольку функциональность еще не реализована в Docker (начиная с 1.9)
Есть предложение ввести "depend_on" в новую сетевую функцию, представленную Docker. Но есть длительные дискуссии об одном и том же @https://github.com/docker/compose/issues/374 Следовательно, после его внедрения функция depend_on может использоваться для заказа запуска контейнера, но на данный момент вам придется прибегнуть к одному из следующих действий:
- запустите nginx, пока сервер php не встанет - я бы предпочел этот
- используйте обходной путь volums_from, как описано выше - я бы не стал использовать это из-за утечки объема в ненужные контейнеры.
Ответ 2
Это можно решить с помощью упомянутой директивы 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
Ответ 3
Вы можете установить директивы max_fails и fail_timeout nginx, чтобы указать, что 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;
}
}
Кроме того, согласно следующему примечанию от докера (https://github.com/docker/compose/blob/master/docs/networking.md), очевидно, что логика повторения для проверки работоспособности других контейнеров не Ответственность за докер и, скорее, контейнеры должны сделать проверку здоровья самостоятельно.
Обновление контейнеров
Если вы измените конфигурацию службы и запустите docker-compose для ее обновления, старый контейнер будет удален, а новый присоединится к сети под другим IP-адресом, но с тем же именем. Запущенные контейнеры смогут найти это имя и подключиться к новому адресу, но старый адрес перестанет работать.
Если какие-либо контейнеры имеют открытые соединения со старым контейнером, они будут закрыты. Контейнер несет ответственность за обнаружение этого состояния, поиск имени снова и повторное подключение.
Ответ 4
Я считаю, что Nginx не учитывает Docker resolver (127.0.0.11), поэтому, пожалуйста, можете ли вы попробовать добавить:
resolver 127.0.0.11
в вашем конфигурационном файле nginx?
Ответ 5
Если вы так потерялись, прочитайте последний комментарий. Я достиг другого решения.
Основная проблема в том, как вы назвали имена сервисов.
В этом случае, если в вашем docker-compose.yml
сервис для php называется "api" или что-то в этом роде, вы должны убедиться, что в файле nginx.conf
строка, начинающаяся с fastcgi_pass
имеет то же имя, что и php оказание услуг. т.е. fastcgi_pass api:9000;
Ответ 6
У меня была та же проблема, потому что в моем docker-compose.yml
были определены две сети: одна бэкэнд и одна веб-интерфейс.
Когда я изменил это для запуска контейнеров в той же сети по умолчанию, все стало работать нормально.
Ответ 7
Имел ту же проблему и решил ее. Пожалуйста, добавьте следующую строку в раздел docker-compose.yml nginx:
links:
- php:waapi_php_1
Хост в разделе конфигурации nginx fastcgi_pass должен быть связан в конфигурации docker-compose.yml nginx.
Ответ 8
Со ссылками есть порядок запуска контейнера. Без ссылок контейнеры могут запускаться в любом порядке (или действительно все сразу).
Я думаю, что старая установка могла поразить ту же проблему, если контейнер waapi_php_1
был медленным для запуска.
Я думаю, чтобы заставить его работать, вы можете создать точку входа nginx script, которая опросит и ждет, когда контейнер php будет запущен и готов.
Я не уверен, что nginx может каким-либо образом автоматически выполнить попытку подключения к восходящему потоку, но если это произойдет, это будет лучший вариант.
Ответ 9
Вы должны использовать что-то вроде docker-gen для динамического обновления конфигурации nginx, когда ваш бэкэнд уже работает.
См:
Я полагаю, что Nginx + (премиальная версия) содержит параметр разрешения (http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream)
Ответ 10
Возможно, лучший выбор, чтобы не связывать проблемы с контейнерами, - это сетевые функции докеры
Но для выполнения этой работы докер создает записи в /etc/hosts для каждого контейнера из назначенных им имен в каждый контейнер.
с docker-compose - x-networking-up - это что-то вроде [Docker_compose_folder] - [Сервис] - [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
Убедитесь, что это одно имя, указанное в вашем файле конфигурации для этой службы. Я уверен, что есть лучшие способы сделать это, но это хороший подход для начала.
Ответ 11
Мой обходной путь (после долгих проб и ошибок):
-
Чтобы обойти эту проблему, мне нужно было получить полное имя Docker-контейнера "upstream", найденное в результате запуска docker network inspect my-special-docker-network
и получения свойства full name
вышестоящего контейнера следующим образом:
"Containers": {
"39ad8199184f34585b556d7480dd47de965bc7b38ac03fc0746992f39afac338": {
"Name": "my_upstream_container_name_1_2478f2b3aca0",
-
Затем использовали это в NGINX my-network.local.conf
файл в location
блока proxy_pass
собственности: (Обратите внимание на добавление GUID на имя контейнера):
location / {
proxy_pass http://my_upsteam_container_name_1_2478f2b3aca0:3000;
В отличие от ранее работавшего, но теперь сломанного:
location / {
proxy_pass http://my_upstream_container_name_1:3000
Наиболее вероятной причиной является недавнее изменение Docker Compose в схеме именования контейнеров по умолчанию, как указано здесь.
Похоже, что это происходит для меня и моей команды на работе с последними версиями образа Docker nginx
:
- Я открыл с ними проблемы в Docker/Compose GitHub здесь
Ответ 12
(новый для nginx) В моем случае это было неправильное имя папки
Для конфигурации
upstream serv {
server ex2_app_1:3000;
}
убедитесь, что папка приложения находится в папке ex2:
ех2/приложение/...
Ответ 13
Стоит упомянуть две вещи:
- Используя тот же сетевой мост
- Использование
links
для добавления хостов resol
Мой пример:
version: '3'
services:
mysql:
image: mysql:5.7
restart: always
container_name: mysql
volumes:
- ./mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: [email protected]
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
Если вы не укажете специальный сетевой мост, все они будут использовать один и тот же мост по умолчанию.
Ответ 14
Добавьте раздел links в конфигурацию вашего 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
Ответ 15
Вот как я это понимаю, лучший способ, о котором я могу думать.
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