web-dev-qa-db-ja.com

Dockerコンテナの変数名を持つNginxリバースプロキシが間違ったファイルを返す

私はたくさん読んでたくさん試しましたが、結局何もうまくいきませんでした。あなたが助けてくれることを願っています。

だからここに私のセットアップです:

Phpmyadminコンテナを含むDocker-composeファイルがあります。私の問題はphpmyadminに限定されていません。これは良い例です。 docker-fileの下(重要な部分)。ご覧のとおり、phpmyadminを https://www.example.com/phpmyadmin/ で利用できるようにしたいと思います。 https://phpmyadmin.example.com/ (サブパスの代わりにサブドメインですが、これは私が望んでいるものではありません)を使用した場合、私のセットアップははるかに簡単になると思います。phpmyadminコンテナーそれ自体は完璧に機能します。

phpmyadmin:
  image: phpmyadmin/phpmyadmin:latest
  container_name: k3633970_phpmyadmin
  restart: always
  environment:
    MYSQL_ROOT_PASSWORD: xxx
    PMA_Host: xxx
    PMA_ABSOLUTE_URI: https://www.example.com/phpmyadmin/
  networks:
   - frontproxy_default
   - backend

次に、Nginxを起動する2番目のdocker-composeファイルがあります。ここでは何も派手ではありません:

nginx:
  image: nginx:Alpine
  restart: unless-stopped
  volumes:
    - ./data/nginx:/etc/nginx/conf.d
  ports:
    - "80:80"
    - "443:443"
  networks:
    - frontproxy_default

第三に、vHost用のNginx構成ファイルがあります。/phpmyadmin /へのすべてのリクエストをphpmyadminコンテナにプロキシし、その他すべての "/"をApache + phpを実行する別のコンテナにプロキシしようとします。以下に示すように、phpmyadminコンテナーへのプロキシパスを実行します。 Dockerコンテナ名を使用すると、すべてがproxy_pass http://k3633970_phpmyadmin/;で機能します(コメント部分を参照)。

しかし、proxy_pass $target;のような変数を使用すると、それは機能しなくなります。 (私と他の人のための将来の参照として関連する問題を説明しているので、投稿は少し長くなります)。何が起こるかというと、phpmyadminのスタートページが読み込まれ、「js/phpmyadmin.js」や「css/phpmyadmin.css」などのJS/CSSファイルが含まれています。 Webブラウザーはファイルをロードしますが、NginxリバースプロキシはCSS/JSファイルを配信せず、スタートページを再度配信します。開始ページが「text/html」として配信されるため、誤ったMIMEタイプが原因で、ブラウザにCSS/JSファイルを含めることができないという警告が表示されます。これにより、最初に間違ったトレースが発生します。実際にはmimeタイプは正しいのに、間違ったファイルが配信されるのに、mimeタイプはfalseです。

私の言いたいことが分かりますか?私はそれをもう一度説明しようとします:

Www.example.com/phpmyadminを読み込んでいます-> mimeタイプtext/htmlのphpmyadminhtmlスタートページが返されます(これは正しいです)。この開始ページにはw​​ww.example.com/phpmyadmin/js/phpmyadmin.jsとwww.example.com/phpmyadmin/css/phpmyadmin.cssが含まれていますが、これはwww.example.com/phpmyadmin/js/phpmyadminに返されます。 .js-> mime type text/htmlのphpmyadminhtmlstart pageが返されます。 www.example.com/phpmyadmin/css/phpmyadmin.css-> phpmyadmin htmlスタートページがMIMEタイプtext/htmlで返されます。

これは私のnginx設定ファイルです。

server {
    listen 443 ssl;
    server_name www.example.com;
    server_tokens off;
    ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;


   location /phpmyadmin/ {
        resolver 127.0.0.11 valid=30s;
        set $target http://k3633970_phpmyadmin/; #Notice the trailing slash!
        proxy_set_header Host $Host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass $target;
    }

# This works, without variables, but this is not what I want
#   location /phpmyadmin/ {
#        resolver 127.0.0.11 valid=30s;
#        set $upstreamx k3633970_phpmyadmin;
#        proxy_set_header Host $Host;
#        proxy_set_header X-Real-IP $remote_addr;
#        proxy_pass http://k3633970_phpmyadmin/;
#         gzip  on;
#    }

    location / {
        resolver 127.0.0.11 valid=30s;
        set $upstream k3633970_vhost_1000303;
        proxy_set_header Host $Host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://$upstream:80;
    }
}

その理由は、Nginxドキュメントからです:

Proxy_passディレクティブがURIで指定されている場合、要求がサーバーに渡されると、場所に一致する正規化された要求URIの部分が、ディレクティブで指定されたURIに置き換えられます。

わかりました。しかし、どうすれば今それを解決できますか?

set $target http://k3633970_phpmyadmin$uri;set $target http://k3633970_phpmyadmin$request_uri;set $target http://k3633970_phpmyadmin/$uri;などで考えられるすべての組み合わせを試しました。有効な組み合わせは見つかりませんでした。

助けてください、私は行き詰まっています-ありがとう!

最後の注意:プロキシパスに変数が必要なのはなぜですか?全体的な理由は次のとおりです。10個のdocker-composeファイルがあり、10個のwordpressスタックとそれぞれ3個のコンテナー(Apache + php/mariabdb/phpmyadmin)と1個のnginxリバースプロキシ)があります。dockerを使用する場合ホストホスト、10個すべてのdocker-composeスタックは、nginxを開始する前に稼働している必要があります。これは不可能であり、テストのために1〜2個のスタックがダウンしている場合があります。/maintenance。変数を使用したアプローチでは、10個のDockerスタックのうち8個だけが稼働している場合でも、nginxを開始できます。

ありがとうございました!

1
schube

Nginxサービスは、「コンテナ名」ではなく「サービス名」を使用してphpmyadminコンテナのIPを解決する必要があります。

また、リクエストをphpmyadminコンテナにプロキシするときは、/ phpmyadminパスをURLに保持する必要があります。末尾にスラッシュを付けると、その部分が削除されるため、末尾にスラッシュを付けないでください。または、正規表現解析を使用して完全なURLを再構築することもできます。

したがって、次のようなものが機能するはずです。

location ~* ^/phpmyadmin/(.*)$ {
  set $query $1;
  set $phpmyadmin phpmyadmin; # Service name in docker-compose file
  proxy_pass http://$phpmyadmin/phpmyadmin/$query$is_args$args; # Rebuild the URL
}
1
Jonathan Rioux

@ jonathan-riouxの助けを借りて、これは現在機能している構成です:

location ~* ^/phpmyadmin/(.*)$ {
    resolver 127.0.0.11 valid=30s;
    set $query $1;
    set $target http://k3633970_phpmyadmin/$query$is_args$args;
    proxy_set_header Host $Host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_pass $target;
}

ありがとうございました!

0
schube