Мережі Docker - nginx: хост [emerg] не знайдено в попередній версії


98

Нещодавно я почав переходити на мережеві функції Docker 1.9 та Docker-Compose 1.5 для заміни використання посилань.

Поки що з посиланнями не було проблем із підключенням nginx до мого сервера php5-fpm fastcgi, розташованого на іншому сервері в одній групі за допомогою 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 працювати лише з одним викликом складання докера?


3
Я теж стикаюся з цим. Я не впевнений, що це помилка з файлом створення, або помилка з самою мережею docker.
jrdn

Відповіді:


26

Існує можливість використовувати "volume_from" як обхідний спосіб, поки не буде введена функція depend_on (обговорена нижче). Все, що вам потрібно зробити, - це змінити файл для створення докера, як показано нижче:

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 може бути використана для замовлення запуску контейнера, але на На даний момент вам доведеться вдатися до одного з наступного:

  1. зробіть спробу nginx, поки сервер php не запуститься - я віддав би перевагу цьому
  2. використовуйте volums_from обхідного способу, як описано вище - я б уникнув використання цього через витік обсягу в непотрібні контейнери.

3
Це не виправило це для мене.
Гійс

@Gijs, якщо ти можеш опублікувати конкретний твій випадок, а що не спрацював, хтось може допомогти на форумі.
Phani

4
volumes_from застаріли
Roma Rush

Я зіткнувся з проблемою в Azure App Service Docker Compose (попередній перегляд) із цим. Також потрібно було переконатися, що будь-який із links:включених мною в nginx використовував те саме ім’я, що і сама служба, як - my-service:my-serviceу цьому прикладі - mongo:mongo.
greg

29

Це можна вирішити за допомогою згаданого 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

Ви можете встановити директиви 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 {
   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;
    }
}

Крім того, згідно з наступною приміткою з докера ( 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 це був приємний улов. Як обхідний шлях можна додати два псевдоніми одного і того ж контейнера, щоб зробити групу з одного контейнера.
Фані

Як альтернативне рішення, я запропонував у тому ж питанні використовувати "volume_from", щоб зв'язати контейнери і змусити їх чекати, поки інші контейнери завантажаться. Це працює для мене.
Фані

7

Я вважаю, що Nginx не бере до уваги вирішувач Docker (127.0.0.11), тому, будь ласка, можете спробувати додати:

resolver 127.0.0.11

у вашому файлі конфігурації nginx?


Додайте кілька вирішувачів, наприкладresolver 127.0.0.11 8.8.8.8;
Леонардо Чая,

1
Ні, оскільки це буде запит у круговій манері, як зазначено в документах: Сервери імен запитуються в круговій манері.
dalore

6

Якщо ви так заблукали, прочитайте останній коментар. Я дійшов іншого рішення.

Основна проблема полягає в тому, як ви назвали імена служб.

У цьому випадку, якщо у вашій docker-compose.ymlслужбі для php називається "api" або щось подібне, ви повинні переконатися, що у файлі nginx.confрядок, що починається з, fastcgi_passмає те саме ім'я, що і служба php. тобтоfastcgi_pass api:9000;


3

У мене була та сама проблема, оскільки в моїй мережі було визначено дві мережі docker-compose.yml: одна серверна і одна зовнішня.
Коли я змінив це для запуску контейнерів в тій самій мережі за замовчуванням, все почало працювати нормально.


Це далеко не відповідь.
dargmuesli

2

Мав таку ж проблему і вирішив її. Будь ласка, додайте наступний рядок до розділу docker-compose.yml nginx:

links:
  - php:waapi_php_1

Хост у розділі конфігурації nginx fastcgi_pass повинен бути зв’язаний всередині конфігурації docker-compose.yml nginx.


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

З першого погляду я пропустив, що моя "веб-" служба насправді не запускається, тому саме 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-файл як run.py в app.ini, який повинен був запускати програму, але це не відбувається
isrj5

0

З посиланнями існує порядок запуску контейнера, який виконується. Без посилань контейнери можуть запускатися в будь-якому порядку (або насправді відразу).

Я думаю, що стара установка могла б спричинити ту саму проблему, якби waapi_php_1контейнер повільно запускався.

Я думаю, що для його роботи ви можете створити скрипт точки входу nginx, який опитує і чекає запуску та готовності контейнера php.

Я не впевнений, чи є у nginx якийсь спосіб повторити автоматичне підключення до висхідного потоку, але якщо він є, це був би кращий варіант.


І як мені проводити опитування?
Аттіла Шеремі,

0

Вам потрібно використовувати щось на зразок docker-gen, щоб динамічно оновлювати конфігурацію nginx, коли ваш сервер запущений.

Подивитися:

Я вважаю, що Nginx + (преміум-версія) теж містить параметр вирішення ( http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream )


0

Мабуть, найкращим вибором, щоб уникнути проблем із зв'язуванням контейнерів, є мережа докерів функції

Але, щоб зробити це, Docker створює записи в / etc / hosts для кожного контейнера з призначених імен для кожного контейнера.

з docker-compose --x-networking -up - це щось на зразок [docker_compose_folder] - [служба] - [інкрементальний номер]

Щоб не залежати від несподіваних змін у цих назвах, слід використовувати параметр

ім'я_контейнера

у вашому 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властивості контейнера вище за течією:

    "Containers": {
         "39ad8199184f34585b556d7480dd47de965bc7b38ac03fc0746992f39afac338": {
              "Name": "my_upstream_container_name_1_2478f2b3aca0",
    
  • Потім використав це у my-network.local.confфайлі NGINX у 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 у їхній схемі імен за замовчуванням для контейнерів, як зазначено тут .

Здається, це відбувається для мене та моєї команди на роботі, з останніми версіями nginxобразу Docker :

  • Я відкрив проблеми з ними на докері / складі GitHub тут

0

(нове для nginx) У моєму випадку це було неправильне ім’я папки

Для конфігурації

upstream serv {
    server ex2_app_1:3000;
}

переконайтеся, що папка програми знаходиться в папці ex2:

ex2 / app / ...


0

ця помилка з'явилася у мене, оскільки моє php-fpmзображення увімкнено cron, і я поняття не маю, чому


0

Моя проблема полягала в тому, що я забув вказати псевдонім мережі в docker-compose.yml у php-fpm

    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. Я хотів би рішення, яке використовує це, частково тому, що посилання мають проблему з круговим посиланням, чого не повинно бути в мережі.
Аттіла Шеремі,

1
У CHANGELOG.md я не бачу linkзастарілих. Мені чогось не вистачає?
nessuno

Я теж там цього не бачив; однак, коли я запускаю 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.
Аттіла Шеремі

Гаразд, я знайшов де застаріння. Єдина ідея, яку я маю: це те, що ви docker-compose.ymlзберігаєте файл у папці з іменемwaapi ?
nessuno

Так, це в папці з назвоюwaapi
Аттіла Шеремі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.