web-dev-qa-db-ja.com

nginx docker container:502不正なゲートウェイ応答

8080ポートをリッスンするサービスがあります。これはコンテナではありません。

次に、公式画像を使用してnginxコンテナを作成しました:

docker run --name nginx -d -v /root/nginx/conf:/etc/nginx/conf.d -p 443:443 -p 80:80 nginx

結局:

# netstat -tupln | grep 443
tcp6       0      0 :::443                  :::*                    LISTEN      3482/docker-proxy
# netstat -tupln | grep 80
tcp6       0      0 :::80                   :::*                    LISTEN      3489/docker-proxy
tcp6       0      0 :::8080                 :::*                    LISTEN      1009/Java

Nginxの構成は次のとおりです。

upstream eighty {
    server 127.0.0.1:8080;
}

server {
    listen 80;
    server_name eighty.domain.com;

    location / {
      proxy_pass                        http://eighty;
    }
}

# curl http://127.0.0.1:8080でこのサーバーに接続できることを確認しました

 <html><head><meta http-equiv='refresh'
 content='1;url=/login?from=%2F'/><script>window.location.replace('/login?from=%2F');</script></head><body
 style='background-color:white; color:white;'>
 ...

しかし、ブラウザを使用してアクセスしようとすると、nginxはbtに502の不正なゲートウェイ応答を伝えます。

私は、コンテナ化されていないプロセスによるオープンとコンテナの間の可視性に関連する問題になる可能性があると考えています。他の非コンテナプロセスによって開かれたポートへのコンテナ接続をコンテナで確立できますか?

[〜#〜] edit [〜#〜]

upstream { server 127.0.0.1:8080; }のログ:

2016/07/13 09:06:53 [error] 5#5: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 62.57.217.25, server: eighty.domain.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", Host: "eighty.domain.com"
62.57.217.25 - - [13/Jul/2016:09:06:53 +0000] "GET / HTTP/1.1" 502 173 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" "-"

upstream { server 0.0.0.0:8080; }のログ:

62.57.217.25 - - [13/Jul/2016:09:00:30 +0000] "GET / HTTP/1.1" 502 173 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" "-" 2016/07/13 09:00:30 [error] 5#5: *1 connect() failed (111: Connection refused) while connecting to upstream, client:
62.57.217.25, server: eighty.domain.com, request: "GET / HTTP/1.1", upstream: "http://0.0.0.0:8080/", Host: "eighty.domain.com" 2016/07/13 09:00:32 [error] 5#5: *3 connect() failed (111: Connection refused) while connecting to upstream, client: 62.57.217.25, server: eighty.domain.com, request: "GET / HTTP/1.1", upstream: "http://0.0.0.0:8080/", Host: "eighty.domain.com"
62.57.217.25 - - [13/Jul/2016:09:00:32 +0000] "GET / HTTP/1.1" 502 173 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" "-"

何か案は?

25
Jordi

問題

Localhostは、コンテナに関しては少し注意が必要です。 Dockerコンテナー内で、localhostはコンテナー自体を指します。これは、次のようなアップストリームを使用することを意味します。

upstream foo{
  server 127.0.0.1:8080;
}

または

upstream foo{
  server 0.0.0.0:8080;
}

あなたはリクエストをローカルホストに渡すようnginxに伝えています。しかし、docker-containerのコンテキストでは、localhost(および対応するIPアドレス)はコン​​テナー自体を指します:

enter image description here

コンテナがホストネットワーク上にない場合、127.0.0.1をアドレス指定することにより、ホストマシンに到達することはありません。

解決策

ホストネットワーキング

ホストと同じネットワークでnginxを実行することを選択できます。

docker run --name nginx -d -v /root/nginx/conf:/etc/nginx/conf.d --net=Host nginx

この場合、ポートを公開する必要はないことに注意してください。

これは動作しますが、Dockerネットワークの利点は失われます。 Dockerネットワークを介して通信する必要がある複数のコンテナがある場合、このアプローチは問題になる可能性があります。 Dockerでnginxをデプロイするだけで、高度なDockerネットワーク機能を使用したくない場合は、このアプローチで問題ありません。

ホストのリモートIPアドレスにアクセスする

別のアプローチは、リモートIPアドレスを追加して、ホストマシンに直接接続するようにnginxアップストリームディレクティブを再構成することです。

upstream foo{
  //insert your hosts ip here
  server 192.168.99.100:8080;
}

コンテナはネットワークスタックを通過し、ホストを正しく解決します。

enter image description here

DNS名があれば、それも使用できます。 dockerがDNSサーバーについて知っていることを確認してください。

49
ShrimpPhaser

私はこのコード行を手伝ってくれましたproxy_set_header Host $http_Host;

server {
   listen            80;
   server_name  localhost;
location / {
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   proxy_set_header X-Forwarded-Proto $scheme;
   proxy_set_header Host $http_Host;
   proxy_set_header X-NginX-Proxy true;

   proxy_redirect off;
   proxy_pass http://myserver;
}

私はこの問題を抱えていましたが、パーミッションの問題のためにDockerコンテナが起動しない問題であることが判明しました。

私の場合、実行中

docker-compose ps 

コンテナがステータス1で起動および終了していないことを示しました。新しいマシンへの移行中に権限が失われたことがわかります。親ディレクトリのスタッフを知っているユーザーへのアクセス許可を調整することで問題が解決し、以前のようにdockerサービスを開始できました

nginx_1_c18a7f6f7d6d | chown: /var/www/html: Operation not permitted
0
Daniel

nginx.sh

ip=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | head -n 1)

docker run --name nginx --add-Host="Host:${ip}" -p 80:80 -d nginx

nginx.conf

location / {
    ...
    proxy_pass http://Host:8080/;
}

それは私のために働く

0
hehe Peng

できることはproxy_passcontainerの観点から見ると、アドレスは実際のホストを指します。

コンテナの観点からHostアドレスを取得するには、Windowsでdocker 18.03(またはそれ以降):

イメージ名がnginxであるホストからコンテナでbashを実行します(Alpine Linux distribution):

 docker run -it nginx /bin/ash

その後、コンテナ内で実行します

/ # nslookup Host.docker.internal

Name:      Host.docker.internal
Address 1: 192.168.65.2

192.168.65.2はホストのIPです。spinusのようなブリッジIPではありません。

私はここで使用しています Host.docker.internal

ホストのIPアドレスは変更されています(ネットワークアクセスがない場合はなし)。 18.03以降では、ホストが使用する内部IPアドレスに解決される特別なDNS名Host.docker.internalに接続することをお勧めします。これは開発目的のためであり、Docker for Windows以外の運用環境では機能しません。

次に、nginx configを次のように変更できます:proxy_pass http://192.168.65.2:{your_app_port};

そしてそれはうまく動作するはずです。

ローカルアプリケーションの実行と同じportを忘れずに指定してください。

0
yami