web-dev-qa-db-ja.com

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

最近、リンクを使用して置き換えるDocker 1.9およびDocker-Compose 1.5のネットワーク機能への移行を開始しました。

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

1つのdocker-compose呼び出しだけでnginxを動作させるにはどうすればよいですか?

69
Attila Szeremi

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に公開されることです。これは望ましくありません。しかし、現時点では、これは使用可能な1つのドッカー固有の回避策です。

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

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

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

これは、現在実装されている(2016)ため、前述のdepends_onディレクティブで解決できます。

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での起動順序の制御

15
czerasz

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#servermax_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秒アップしていると想定しています。自分でスクリプトをテストして、試してみてください!

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の責任ではなく、コンテナ自体が健全性チェックを行う必要があります。

コンテナの更新

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

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

8
Phani

NginxはDockerリゾルバー(127.0.0.11)を考慮に入れないので、追加してみてください:

resolver 127.0.0.11

あなたのnginx設定ファイルに?

4
Thomas Decaux

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

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

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

3
julian

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

2
smola

同じ問題を抱えて解決しました。 docker-compose.yml nginxセクションに次の行を追加してください:

links:
  - php:waapi_php_1

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

1
st0at

私の回避策(多くの試行錯誤の後):

  • この問題を回避するために、docker network inspect my-special-docker-networkを実行して完全なnameを取得することで見つかった、「上流」Dockerコンテナーのフルネームを取得する必要がありましたアップストリームコンテナーのプロパティなど:

    "Containers": {
         "39ad8199184f34585b556d7480dd47de965bc7b38ac03fc0746992f39afac338": {
              "Name": "my_upstream_container_name_1_2478f2b3aca0",
    
  • 次に、my-network.local.confプロパティのlocationブロックにある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

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

これは、Docker nginxイメージの最新バージョンで、私と職場の私のチームで起こっているようです。

  • Docker/compose GitHubでそれらの問題をオープンしました here
0
arcadia_168

(nginxの新機能)私の場合、間違ったフォルダー名でした

構成用

upstream serv {
    server ex2_app_1:3000;
}

アプリフォルダーがex2フォルダーにあることを確認します。

ex2/app/...

0
vijeth.ag

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

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

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

Nginxがアップストリームへの接続を自動的に再試行する方法を持っているかどうかはわかりませんが、もしそうなら、それはより良いオプションでしょう。

0
dnephin

コンテナのリンクの問題を回避するための最良の選択は、おそらくdocker networking機能です

しかし、これを機能させるために、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
JorelC

言及する価値のある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: [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

特別なネットワークブリッジを指定しない場合、それらはすべて同じデフォルトブリッジを使用します。

0
NOZUONOHIGH

バックエンドが起動しているときに、nginx設定を動的に更新するには、docker-genなどを使用する必要があります。

見る:

Nginx +(プレミアムバージョン)には解決パラメーターも含まれていると思います( http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream

0
Laurent B