web-dev-qa-db-ja.com

Nginx proxy_passルートと特定のURLのみ

既存のWebアプリの新しいバージョンで作業しているときに、ルート(/)を転送するnginxと複数の特定のURIを(proxy_passを使用して)v2インフラストラクチャに転送する必要がありますが、指定されていないURIはv1に転送する必要があります。

location = /specific_uri1
        proxy_pass http://v2.webapp.com;
        proxy_set_header Host       v2-test.webapp.com;
        add_header       X-version  v2;
        add_header       X-node     $hostname;
}

location = /specific_uri2
        proxy_pass http://v2.webapp.com;
        proxy_set_header Host          v2-test.webapp.com;
        add_header       X-version     v2;
        add_header       X-node        $hostname;
}

location / {
        proxy_pass http://v2.webapp.com;
        proxy_set_header Host          v2-test.webapp.com;
        add_header       X-version     v2;
        add_header       X-node        $hostname;
}

location /(.*)$ {
        proxy_pass http://v1.webapp.com;        
        proxy_set_header   Host         v1-test.webapp.com;
        add_header         X-version    v1;
        add_header         X-node       $hostname;
}

最後の場所ディレクティブは決して一致しないため、宣言されていないものはすべてv2 Webアプリに分類されます。 nginxがディレクティブを処理する方法について、私は間違いを誤解しています。

私は多くの構成をテストしましたが、どれも私の場合には機能しません。

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

更新:

次のブロックで構成を更新しました。

location ~* /specific_uri1/ {
        proxy_pass http://v2.webapp.com:8008;
        proxy_set_header Host       v2-test.webapp.com;
        add_header              X-version     v2;
        add_header              X-node   $hostname;
}


location = / {
        proxy_pass http://v2.webapp.com:8008;
        proxy_set_header        Host    v2-test.webapp.com;
        add_header              X-version     v2;
        add_header              X-node   $hostname;
}

location / {
        proxy_set_header        Host    v1.webapp.com;
        proxy_pass      http://v1-test.webapp.com;
        add_header      X-version     v1;
        add_header      X-node   $hostname;
}

リクエストされたすべてのURIは正しいバージョンに転送されますが、/ specific_uri1および/(ルート)のアセットはv2の代わりにv1からフェッチされるため、http 404エラーが発生します。私のアセットは/js/main.js?v=0.9.0-sprint14のようなURIから読み込まれるので、最後のロケーションブロックはそれらに一致すると思います。アプリの両方のバージョンで同じフォルダーツリーを使用しているため、/ jsまたは/ imgの場所を指定できません。これを処理する正しい方法は何でしょうか?

2
cyrilv

location /は任意の場所に一致します-/のみに一致させたい場合は、location = /を使用する必要があります。詳細は このドキュメント を参照してください。

また、正規表現の場所に~または~*演算子がありません。ただし、質問の最後の場所ブロックはlocation /である必要があります。

単一の正規表現を使用して、構成を簡略化できます。

location ~* ^/(|specific_uri1|specific_uri2)$ {
    proxy_pass http://v2.webapp.com;
    proxy_set_header Host          v2-test.webapp.com;
    add_header       X-version     v2;
    add_header       X-node        $hostname;
}

location / {
    proxy_pass http://v1.webapp.com;        
    proxy_set_header   Host         v1-test.webapp.com;
    add_header         X-version    v1;
    add_header         X-node       $hostname;
}
2
Richard Smith