nginx proxy_pass を使用して Discourse コンテナに転送し、Discourse からホストサーバーへのリンクを設定

Discourse チーム、こんにちは。

ホストマシンで nginx サーバーを、そして Docker 上で標準的な Discourse コンテナを稼働させています。基本的には、ホスト側の nginx がいくつか特定の HTTP フォルダを配信し、それ以外は proxy_pass 経由で Discourse コンテナにフォワードする構成です。

私の理解では、この問題の核心は、ホスト側の nginx 設定ファイルに /xyz という location が定義されており、これはホスト側の nginx が処理し、一方で / という location は Discourse コンテナへの proxy_pass として定義されている点にあります。

私のユースケースでは、Discourse の投稿として my.domaiin.com/xyz/some.html のようなリンクを貼る必要があります。つまり、Discourse 内のリンクがホスト側の nginx が配信するページを指している状態です。

これは最後の Discourse アップデートまでは正常に動作していました。しかし現在、これらのリンクをクリックすると Discourse の「見つかりません」ページが表示されてしまいます。一方、リンクのターゲットをコピーして新しいタブで開く場合は期待通りに動作します。

私は低レベルのプロトコルについてはある程度理解していますが、プロトコルスタックの上位層になるほど知識が不足しています。

現在の仮説は以下の通りです:Discourse 側の nginx が接続を保持(keepalive?)しているため、ホスト側の nginx が新しいリクエストパスを解析して正しいサーバーを選択する機会を逃しているのではないかということです。つまり、接続されたリクエストは保持されたままコンテナへ渡され、その結果、/xyz へのリクエストは、そのフォルダを知らない Discourse 側で処理されてしまうのではないか、と。

この問題にはどのように対処すべきでしょうか?もし簡単な解決策がない場合でも、いくつかのヒントや、適切な HTTP プロトコルの知識に基づいた詳しい説明があれば、大変助かります。

よろしくお願いいたします。

補足:もしこれが本当にキープアライブの問題であれば、キープアライブを無効化してある程度のオーバーヘッドを受け入れることに全く問題ありません。このインストールは大量のユーザーを想定していません。

考えてみると、ホスト側の nginx も名前付きパイプをリッスンするように設定し、そのパイプを Discourse コンテナに公開する必要があります。さらに、カスタムフォルダ /xyz を Discourse の nginx 設定に追加して、新たに作成したパイプを介して proxy_pass する必要があります(詳細を解決した上で、例えばホスト側の nginx を先に起動しないと、docker-compose が名前付きパイプを正しく公開しないといった点など)。

それでも、ご協力をいただければ幸いです :wink:

これは、Ember.JS のルーターが Discourse アプリケーションがサポートするパスの完全なリストを把握しており、サーバーに該当コンテンツがないことを認識しているため、404 ページがクライアント側でレンダリングされることに起因します。

ファイルを別のサブドメインに配置してください。