web-dev-qa-db-ja.com

Nginx動的proxy_passが正しく解決されない

Nginxの設定で問題が発生しました。解決策をWebで検索しましたが、いくつかの部分がありますが、それでも適切な設定を行うことができません。

ドメインを登録しました。たとえば、www.example.comとします。レジストラサイトですべてを構成しました。www.example.comへのpingとwww。*。example.comは成功します。

ポート8080でリッスンしているマシンでApache Tomcatを実行しています。動的なproxy_passを設定したいと思います。したがって、Tomcatで実行されているアプリケーションMyAppがあり、localhost:8080/MyAppを介して到達できる場合、www.MyApp.example.comで到達できるようにしたいので、基本的にサブドメインはTomcatのアプリケーションの名前になります。

これが私のnginx設定です:

server {
  server_name ~^(www\.)?(?<sub_domain>.+)\.example\.com$;
  listen 80;

  location / {
     proxy_pass http://localhost:8080/$sub_domain/;
  }
}

Www.myapp.example.comにアクセスすると、http://localhost:8080/myappにリダイレクトされます-つまり、ブラウザで文字どおりhttp://localhost:8080/myappになってしまいます。

ただし、nginxセットアップで正規表現を次のように変更した場合:

server {
      server_name www.myapp.example.com myapp.example.com
      listen 80;

      location / {
         proxy_pass http://localhost:8080/myapp/;
      }
    }

その後、すべてが魅力のように動作します。私はそれがリゾルバーで何かをしなければならないことを知っています、私はすでにnginxにリゾルバーを入れてみましたが、何も変更しません。

ここで何が欠けていますか?

//編集:

これが私の設定です。 www.myapp.example.com/loginではなく、www.myapp.example.com/myapp/loginにリダイレクトされます。正規表現を変更しましたが、同じです。

  http {

    upstream backend {

             server 127.0.0.1:8080;

    }

    server {                                                         
          server_name ~^(www\.)?(?<sub_domain>.+)\.example\.com$;
          listen 80;                                                        


           location / {
               proxy_set_header "Host" $Host;
               proxy_pass http://backend/prefix-$sub_domain/;

               proxy_redirect http://$Host/prefix-$sub_domain/ http://$Host;

           }

    }

カール:

* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /prefix-myapp/ HTTP/1.1
> User-Agent: curl/7.35.0
> Accept: */*
> Host: www.myapp.example.com
>
< HTTP/1.1 302 Found
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Set-Cookie: JSESSIONID=E609EB96D8F27FD6F4E7F9ED9ACA5245; Path=/prefix-myapp/; HttpOnly
< Location: http://www.myapp.example.com/prefix-myapp/login;jsessionid=E609EB96D8F27FD6F4E7F9ED9ACA5245
< Content-Length: 0
< Date: Tue, 21 Oct 2014 16:48:05 GMT
<
* Connection #0 to Host 127.0.0.1 left intact

編集://

ザビエルに感謝します!次の2行を追加すると役立ちました。

proxy_pass http://backend/prefix-$domain$request_uri;
proxy_redirect http://$Host/prefix-$domain http://$Host;

2さらに質問:

  1. この構成はパフォーマンスに大きな影響を与えますか?
  2. $ request_uri(例:JSESSIONID = 1233 ....)から何かを除外できますか?

重ねて感謝します!これを理解するのに一週間かかりました!

6
Stugal

proxy_passディレクティブで変数を使用している場合、nginxは次の場合を除いてランタイム解決を使用します。

  • ターゲットサーバーはIPアドレスとして宣言されます
  • ターゲットサーバー名は上流サーバーグループの一部です
  • ターゲットサーバー名は既に解決されています(たとえば、別のサーバーブロックのサーバー名と一致します)

ここでは、localhostはDNSによって解決されない可能性があるため、ランタイムリゾルバーは役に立ちません。また、ここでそれを明確に回避できるため、ランタイム解決を行うことは無駄です。

したがって、2つの単純なソリューション:

  • 127.0.0.1を使用
  • pstream block を宣言します(サーバー名またはターゲットサーバーのプールがある場合)

次に、プロキシサーバーのリダイレクトを正しくする必要があります。だからどちらか:

  • プロキシターゲットがホストヘッダーを処理し、次のようにパススルーします。

    proxy_set_header "Host" $Host;

  • プロキシターゲットがリダイレクトのホストヘッダーを処理できないため、nginxを使用してリダイレクトを書き換える必要があります。

    proxy_redirect http://$proxy_Host/$sub_domain http://$Host;

ただし、Hostヘッダーをまったくサポートしていない場合、リンクは壊れます。

9
Xavier Lucas