Dockerコンテナーでnginxをリバースプロキシとして設定し、コンテナー外のサイトにリンクします。私は次のようにvhost構成を設定しています(ホームアシスタントの場所の前に^〜を追加してみました):
server { # simple reverse-proxy
listen 80;
location / {
proxy_pass http://192.168.1.99:6789;
}
location ^~ /home-assistant {
proxy_pass http://192.168.1.99:8123/;
}
location /calibre-web/ {
proxy_pass http://192.168.1.99:8181/;
}
}
ホームアシスタントとcalibre-webサイトの両方でページが読み込まれますが、他のすべてのアイテム(画像、CSSなど)で404エラーが発生します。 アプリケーションのリンクをクリックしようとすると、192.168.1.99/site-folder/fileではなく、192.168.1.99/fileにリンクされます。以下は、ログのいくつかのレコードです(1つの200応答と他の404応答に注意してください)。ここで何が悪いのですか?助けてくれてありがとう。
192.168.1.6 - randy [15/Aug/2016:03:15:42 +0000] "GET /frontend/panels/dev-template-0a099d4589636ed3038a3e9f020468a7.html HTTP/1.1" 404 199 "http://192.168.1.99/home-assistant/" "Mozilla/5.0 (X11; CrOS x86_64 8350.60.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.85 Safari/537.36"
192.168.1.6 - randy [15/Aug/2016:03:15:42 +0000] "GET /frontend/panels/logbook-66108d82763359a218c9695f0553de40.html HTTP/1.1" 404 199 "http://192.168.1.99/home-assistant/" "Mozilla/5.0 (X11; CrOS x86_64 8350.60.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.85 Safari/537.36"
192.168.1.6 - randy [15/Aug/2016:03:17:54 +0000] "GET /home-assistant/ HTTP/1.1" 200 1654 "-" "Mozilla/5.0 (X11; CrOS x86_64 8350.60.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.85 Safari/537.36"
192.168.1.6 - randy [15/Aug/2016:03:17:55 +0000] "GET /static/icons/favicon-192x192.png HTTP/1.1" 404 91 "http://192.168.1.99/home-assistant/" "Mozilla/5.0 (X11; CrOS x86_64 8350.60.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.85 Safari/537.36"
192.168.1.6 - randy [15/Aug/2016:03:17:55 +0000] "GET /static/core-457d5acd123e7dc38947c07984b3a5e8.js HTTP/1.1" 404 91 "http://192.168.1.99/home-assistant/" "Mozilla/5.0 (X11; CrOS x86_64 8350.60.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.85 Safari/537.36"
これは私のルートnginx.confのコピーです 。エラーはここのどこかにあると思いますが、どこにあるのかわかりません。
元のアプリケーションにとって不明な場所からのリクエストをproxy_passしようとしています。 Dockerコンテナアプリケーションでは、Webサイトのルート(http://192.168.1.99:8123/
)からアクセスされていると見なしているため、/
または/home-assistant/
ではなく、/calibre-web/
に関連するすべてのURLを生成します。
この問題を解決する方法はたくさんあります。自分に最適な方法を選択してください。
まず第一に、結果をクライアントに送信する前に、プロキシされたアプリケーションから受信したすべてのリンクを ngx_http_sub_module で置き換えることができます。デフォルトでは有効になっていないため、ディストリビューションにない場合は ソースからnginxをコンパイル する必要があります(このモジュールの可用性を確認するには、nginx -V
を実行します。これにより、--with-http_sub_module
構成パラメータに沿ったどこか)。
この方法を選択する場合は、次のディレクティブを構成に追加します。
location ^~ /home-assistant {
rewrite ^/home-assistant(/.*)$ $1 break;
proxy_pass http://192.168.1.99:8123/;
sub_filter "<head>" "<head><base href=\"${scheme}://${Host}/home-assistant\">";
}
Dockerコンテナー内のアプリケーションをルートではなく/home-assistant
に移動すると、ルート/
ではなく、そのパスに関連する提供コンテンツにすべてのURLが生成されます。これは明白な(そしておそらく最も簡単な)ソリューションであり、nginxの構成をまったく変更する必要がありません(Docker内で構成を編集する必要はありません)。
Referer
ヘッダーに基づいて、使用するアップストリームを決定します。 ここから取得 。自分では本番では使用しませんが、かなりスマートに見えます(css/jsファイルでのみ機能することに注意してください)。
location ~* ^/(css|js)/.+\.(css|js)$ {
#checking if referer is from home-assistant
if ($http_referer ~ "^.*/home-assistant"){
return 417;
}
#checking if referer is from calibre-web
if ($http_referer ~ "^.*/calibre-web"){
return 418;
}
}
error_page 417 /home-assistant$request_uri;
error_page 418 /calibre-web$request_uri;
location ^~ /home-assistant {
proxy_pass http://192.168.1.99:8123/;
}
location /calibre-web {
proxy_pass http://192.168.1.99:8181/;
}
私があなただったら、#2を使用します。必要なものを取得するための最も簡単でエラーが発生しにくい方法として、コンテナー内でアプリを移動します。
追伸バックエンドがnginxと同じサーバー上にあるため、静的ファイルをハードドライブから直接提供できることを完全に忘れていました。アプリケーションに依存した構成が必要になりますが、結果として最も効率的なソリューションが得られます。
1つの解決策は、proxy_pass
ディレクティブでURIを渡さないことです。
location ^~ /home-assistant {
proxy_pass http://192.168.1.99:8123;
}
location ^~ /calibre-web/ {
proxy_pass http://192.168.1.99:8181;
}
/
ステートメントのポート番号の後にproxy_pass
文字がないことに注意してください。つまり、nginxはサーバーに送信されたURIをアプリサーバーに渡します。
/
文字(URI)を使用すると、要求URIがそれで置き換えられます。
この動作は http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass に記載されています