Docker Networking-nginx:[emerg]ホストがアップストリームに見つかりません


99

最近、Docker1.9およびDocker-Compose1.5のネットワーク機能への移行を開始し、リンクの使用を置き換えました。

これまでのところ、リンクに関しては、nginxがdocker-composeを介して1つのグループ内の別のサーバーにあるphp5-fpmfastcgiサーバーに接続することに問題はありませんでした。新たに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

これはdefault.confnginxの私のものです:

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

単一のdocker-compose呼び出しのみでnginxを機能させるにはどうすればよいですか?


3
私もこれに遭遇しています。作成ファイルのエラーなのか、Dockerネットワーク自体のバグなのかわかりません。
jrdn 2015年

回答:


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

上記のアプローチの大きな注意点の1つは、phpのボリュームがnginxに公開されることですが、これは望ましくありません。ただし、現時点では、これは使用できるDocker固有の回避策の1つです。

depends_on機能 これはおそらく未来的な答えでしょう。機能はまだDockerに実装されていないため(1.9以降)

Dockerによって導入された新しいネットワーク機能に「depends_on」を導入する提案があります。しかし、同じ@ https://github.com/docker/compose/issues/374については長期にわたる議論があります。したがって、実装されると、機能depends_onを使用してコンテナーの起動を注文できますが、瞬間、あなたは次のいずれかに頼らなければならないでしょう:

  1. PHPサーバーが起動するまでnginxを再試行します-私はこれを好むでしょう
  2. 上記の回避策からvolums_fromを使用します-不要なコンテナへのボリュームリークのため、これの使用は避けます。

3
これは私のためにそれを修正しませんでした。
gijs 2016

@Gijs正確なケースとうまくいかなかったものを投稿できれば、誰かがフォーラムで助けてくれるでしょう。
ファニ2016年

4
volume_fromは非推奨です
Roma Rush

これでAzureApp 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

nginxのmax_failsおよびfail_timeoutディレクティブを設定して、nginxがアップストリームサーバーが使用できない状態で失敗する前に、コンテナーへのx回の接続要求を再試行する必要があることを示すことができます。

インフラストラクチャとセットアップ全体が開始される速度に応じて、これら2つの数値を調整できます。以下の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の責任ではなく、コンテナーが自身でヘルスチェックを行う必要があります。

コンテナの更新

サービスの構成を変更し、docker-compose upを実行して更新すると、古いコンテナーは削除され、新しいコンテナーは異なるIPアドレスで同じ名前でネットワークに参加します。実行中のコンテナはその名前を検索して新しいアドレスに接続できますが、古いアドレスは機能しなくなります。

古いコンテナへの接続が開いているコンテナがある場合、それらは閉じられます。この状態を検出し、名前を再度検索して再接続するのは、コンテナーの責任です。


3
これは機能しません。nginxドキュメントのこのセクションの最後にある警告を読んでください:「グループにサーバーが1つしかない場合、max_fails、fail_timeout、slow_startパラメーターは無視され、そのようなサーバーは利用できないとは見なされません。」
Ferguzz 2016年

1
@Ferguzzはいいキャッチでした。回避策として、同じコンテナの2つのエイリアスエントリを追加して、同じコンテナからグループを作成できます。
ファニ2016年

別の解決策として、同じ質問で「volumes_from」を使用してコンテナーをリンクし、他のコンテナーがロードされるまで待機させることを提案しました。これは私のために働いています。
ファニ2016年

7

NginxはDockerリゾルバー(127.0.0.11)を考慮していないと思いますので、追加してみてください。

resolver 127.0.0.11

nginx構成ファイルにありますか?


次のような複数のリゾルバーを追加しますresolver 127.0.0.11 8.8.8.8;
Leonardo Chaia 2017年

1
ドキュメントに記載されているように、ラウンドロビンでクエリを実行するため、いいえ。ネームサーバーはラウンドロビン方式でクエリされます。
dalore 2018

6

あなたがとても迷っているなら、最後のコメントを読んでください。私は別の解決策に到達しました。

主な問題は、サービス名の付け方です。

この場合、docker-compose.ymlでphpのサービスが「api」などと呼ばれている場合は、ファイル内nginx.confでで始まる行がfastcgi_passphpサービスと同じ名前であることを確認する必要があります。すなわちfastcgi_pass api:9000;


3

docker-compose.ymlバックエンドとフロントエンドの2つのネットワークが定義されていたため、同じ問題が発生しました。
同じデフォルトネットワークでコンテナを実行するように変更すると、すべてが正常に機能し始めました。


これは答えとは程遠いです。
dargmuesli

2

同じ問題があり、それを解決しました。docker-compose.ymlnginxセクションに次の行を追加してください。

links:
  - php:waapi_php_1

nginx config fastcgi_passセクションのホストは、docker-compose.ymlnginx構成内でリンクする必要があります。


1

言及する価値のある2つのこと:

  • 同じネットワークブリッジを使用する
  • 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: 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に配置しました。これは、アプリを実行するはずですが、実行されません
isrj 52

0

リンクを使用すると、コンテナの起動順序が適用されます。リンクがないと、コンテナは任意の順序で(または実際には一度に)開始できます。

waapi_php_1コンテナの起動が遅かった場合、古いセットアップでも同じ問題が発生した可能性があると思います。

それを機能させるには、phpコンテナが開始されて準備ができるのをポーリングして待機するnginxエントリポイントスクリプトを作成できます。

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-networkname

    "Containers": {
         "39ad8199184f34585b556d7480dd47de965bc7b38ac03fc0746992f39afac338": {
              "Name": "my_upstream_container_name_1_2478f2b3aca0",
    
  • 次に、プロパティmy-network.local.conflocationブロックのNGINXファイルでこれを使用しました:(proxy_passコンテナ名にGUIDが追加されていることに注意してください):

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

以前は機能していたが現在は壊れているのとは対照的に:

    location / {
        proxy_pass http://my_upstream_container_name_1:3000

最も可能性の高い原因は、ここにリストされているように、コンテナーのデフォルトの命名スキームでのDockerComposeへの最近の変更です

これは、Dockernginxイメージの最新バージョンを使用して、私と職場のチームで発生しているようです。

  • Docker / ComposeGitHubで問題をここで開きまし

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は、Dockerのネットワークの使用を支持して1週間前にリリースされたバージョン1.9で非推奨とマークしました。これを使用したソリューションが欲しいのですが、これは、ネットワークにあるべきではない循環リンクにリンクに問題があるためです。
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.
アッティラSzeremi

わかりました、私は非推奨がどこにあるかを見つけました。私が持っている唯一のアイデアは次のとおりです。あなたはdocker-compose.ymlという名前のフォルダにファイルしますwaapiか?
nessuno 2015

はい、それはwaapi
Attila Szeremi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.