Docker ComposeでアプリのNginxの前にCaddyを配置

私は自分のDiscourseフォーラムサーバーのうちの1つをアップグレードし、IONOS Cloud PanelのファイアウォールでTCPだけでなくUDP 443も開くように設定しました(私は英国からアクセスしています)。

この特定のフォーラムはユーザー数が多くありませんが、カテゴリが多数あるため、CDNは使用していません。

nginxを介してIPジオロケーションを正しく設定する際にいくつかの困難がありましたが、現在フォーラムは問題なく動作しており、/logsにもエラーはありません。

Docker Composeを使用してプロキシログのローテーションを設定しており、Caddyがプロキシログ内の機密フィールドを自動的に削除してくれることに感謝しています。これは以前Nginxではあまり気づかなかった点です。ただし、Discourseを本番環境で2年間使用してきて、プロキシログを確認したのは2回だけでした。

Beginner docker install guideから、現在もう少しモバイルフレンドリーなフォーラムになるまでの過程で、私が実行したコマンドと、それを実行した際に何が起こったかを解説したガイドを公開した場合、どれくらいの関心があるのかを知りたいと考えています。将来のメンテナンス用のコマンド(例:Caddyを新しいリリースにアップグレードするコマンドなど)も含めることができますが、これらのコマンドはまだIONOSのL VPSでテストしていません。

参考までに、このPRがあります:Add Caddy web server template as nginx alternative - Pull Request #952 - discourse/discourse_docker - GitHub

ありがとうございます、そのPRは見ていませんでした。興味深いですね。私の環境は少し異なり、Discourseのnginx Webサーバーをそのまま残し、CaddyをDocker Composeで別途実行して、主にエッジでHTTP/3を提供しています。

Discourse側には小さな変更が1つあります。Unixソケット経由でリクエストが届いた際に、nginxがCaddyのX-Forwarded-For値を実クライアントIPとして使用するように、永続的なapp.ymlフックを追加しました。当初はCaddyのX-Real-IPワークアラウンドが必要でしたが、nginx側の修正を追加した後、それを削除してDiscourseが正しいクライアントIPを記録していることを確認できました。

また、Caddyの設定でQUIC 0-RTT/早期データを明示的に無効にし、HTTP/3は有効のままにしました。これは、追加の早期データのエッジケースを避けるためです。

私のアプローチにより、CaddyのHTTPアクセスログをサイトレベルで有効にすることができ、これにより機密性の高い認証情報ヘッダーのCaddyデフォルトのマスク処理が得られます。生成されるDockerのjson-fileログは25 MB × 3でローテーションしています。現在、PRにはCaddyのグローバルオプションにログローテーションブロックが含まれていますが、Caddyのドキュメントでは、これはランタイムログの設定であり、HTTPアクセスログの設定ではないと説明されています。

したがって、完全に untouched の標準インストールというわけではありませんが、nginxをCaddyに完全に置き換えるアプローチとも異なります。

そのPRを詳しく見てみます。現時点では、すぐにガイドを作成するよりも、このアプローチに関心がある人が十分いて、ステップバイステップのガイドを作成する価値があるかどうかを主に確認したいと考えています。

上記の発言に対する訂正・補足です。

当初、結果を以下のように説明しました。

モバイルに優しいフォーラム、と。

私が気づいたことの1つとして、iOS Safari PWAを開いた際の初期のラウンドトリップ(往復通信)が以前は遅すぎると感じられたという点がありました。


しかし、後の返信で以下の発言を含んだことを今後悔しています。

0-RTTの無効化は、クライアントIPの問題を診断する際に試したもののようですが、必要ではなかったようです。0rtt offがすでに設定されている間も、unix:に関連するPostgreSQLのエラーは両方とも続きました。

これらのエラーを解決した変更は、むしろ、Unixソケット経由でリクエストが届いた際に、実際のクライアントIPとしてCaddyのX-Forwarded-For値を使用するようにnginxを修正する永続的なapp.ymlフックでした。

そのため、今では0rtt offの設定を削除し、Caddyのデフォルトの動作に戻しました。HTTP/3は引き続き動作しており、正しいクライアントIPがDiscourseに渡り続けています。

したがって、最終的に十分な関心があればステップバイステップのガイドを作成する場合、QUIC 0-RTTの無効化を構成の必須部分としては含めません

Vanilla Nginx でも可能です:https://quic.nginx.org/

ありがとうございます。Discourseのappコンテナに現在同梱されているnginxを確認しましたが、ご指摘の通り、直接HTTP/3を提供できるようです:

nginx 1.26.3-3+deb13u7
OpenSSL 3.5.6
--with-http_v3_module

したがって、Discourseの既存のnginxから直接HTTP/3を提供することは、確かに現実的な代替手段です。

ただし、この特定のセットアップにおいてCaddyを依然として好む理由の一つは、0-RTT(ゼロラウンドトリップタイム)機能です。上記の修正の後、CaddyのデフォルトのQUIC 0-RTT動作を再有効化し、iOS SafariのPWA(プログレッシブウェブアプリ)で、改善しようとしていた読み込み体験に著しい向上があることに気づきました。

nginxのドキュメントから判断する限り、1.29.1以前のnginxバージョンはOpenSSLでビルドされている場合、ssl_early_dataの設定に関係なく0-RTTを有効化できません。したがって、私のDiscourseコンテナに現在あるnginx 1.26.3はHTTP/3は対応していますが、この特定の最適化(0-RTT)はサポートしていません。

そのため、HTTP/3のためだけにCaddyが必要だと仮定するのではなく、この2つのアプローチを比較することに興味があります。