リバースプロキシと各HTTPバックエンドを1つの共有ユーザー定義ネットワークに接続し、データベースはプライベートなアプリネットワークに置きます。
プロキシがユーザー定義ブリッジ上でComposeのサービス名を解決できる場合、すべてのバックエンドのポートをNASホストに公開する必要はありません。2ネットワーク構成により、プロキシからWebバックエンドへの経路を制御しながら、データベースには各アプリケーションからのみ到達できるようにします。ネットワークの所有者を定義し、曖昧なエイリアスを避け、どのサービスに外向きアクセスが必要かを決め、ホストポートが閉じたままであることを確認してください。
意図した到達可能性マトリックスを作成する
すべての接続を一覧にします。クライアントからプロキシ、プロキシからバックエンド、バックエンドからデータベース、バックエンドから外部API、管理者からメンテナンス用エンドポイントまでを含めます。プロトコル、ポート、DNS名、および経路がホストを通過するかどうかを記載します。
通常、ポート80と443を公開するのはリバースプロキシだけにします。バックエンドは、ホストのportsマッピングなしで、Dockerネットワークにアプリケーションポートを公開します。明示的な管理経路が必要な場合を除き、データベースはアプリ専用ネットワークにのみ接続します。
安定した一意のサービス名またはネットワークエイリアスを選択します。Docker DNSは共有ユーザー定義ネットワーク上のサービスを解決しますが、複数のComposeプロジェクトを同じプロキシネットワークに接続すると、webのような一般的なエイリアスが衝突する可能性があります。
共有プロキシネットワークとプライベートアプリネットワークを作成する
プロキシネットワークを一度作成し、各アプリケーションプロジェクトで外部ネットワークとして指定して、プロキシと対象のバックエンドを接続します。これにより、個々のComposeプロジェクトを再作成してもネットワークの識別情報を安定させられます。
各アプリについて、別個のデフォルトネットワークまたは名前付きプライベートネットワークを定義し、バックエンドとデータベースを接続します。バックエンドは、プロキシからのトラフィックとプライベートな状態の間を制御された形で橋渡しする存在になります。プロキシはデータベースネットワークに参加させないでください。
Composeネットワーク定義のドキュメントでは、Composeにおける外部ネットワークとサービス接続について説明しています。外部ネットワークはアプリケーションスタックの外部でライフサイクルを管理するものとして扱います。デプロイ時には、Composeが作成または削除すると想定せず、ネットワークの存在を確認する必要があります。
networks:
proxy:
external: true
app-private:
internal: true
services:
web:
networks: [proxy, app-private]
db:
networks: [app-private]
不要なホストポートを削除し、外向き通信を確認する
プロキシ経由のルートが機能したら、バックエンドのホストポート公開を削除します。exposeの宣言はコンテナポートを記録できますが、ファイアウォールではありません。どのコンテナが接続できるかは、ネットワークへの参加状況によって決まります。
internal: trueは、参加メンバーが本当に外部経路を必要としないネットワークに限って使用してください。IDプロバイダー、Webフック、パッケージサービス、リモートAPIを呼び出すバックエンドは、内部専用ネットワークでは動作しない可能性があります。アプリケーションの設計上必要であれば、外向き通信が可能な2つ目のネットワークを使用します。
自動プロキシ検出に使用するDockerソケットを保護します。読み取り専用のバインドマウントにより誤った書き込みは減らせますが、ソケットが無害になるわけではありません。より限定された制御範囲を実現するには、制限付きソケットプロキシまたは静的設定を使用します。
サービスDNS、ポート公開、分離を確認する
プロキシコンテナからバックエンドのサービス名を解決し、コンテナポート上のヘルスエンドポイントにリクエストします。無関係なコンテナからは、そのコンテナが意図的にプロキシネットワーク上にない限り、名前または接続が利用できないことを確認します。
別のLAN機器からNASホストをスキャンし、プロキシのポートだけが開いていることを確認します。次に、公開ホスト名を通じてTLS、転送ヘッダー、WebSocketアップグレード、大容量アップロード、アプリケーションのリダイレクトをテストします。ホームサーバーサービスマップには、ホームサーバーのサービスマップの一部としてプロキシネットワークを記録してください。
ロールバックでは、診断目的に限って以前のポートマッピングを復元し、恒久的な隠れた依存関係にはしないでください。プロキシがデータベースへの直接アクセスを必要とする場合、エイリアスが誤ったプロジェクトにルーティングされる場合、またはホストポートを削除すると文書化されていない連携が壊れる場合は、作業を中止します。
よくある質問
外部Dockerネットワークは自動的に安全性を高めますか?
いいえ。外部であることが示すのはライフサイクルの所有者であり、安全性ではありません。一般に、接続されたすべてのコンテナは、ネットワークドライバーとホストのファイアウォール動作に応じて通信できます。
バックエンドサービスでもexposeを宣言すべきですか?
ユーザー定義ネットワーク上の接続に必須ではありませんが、想定するコンテナポートを記録する目的で使用できます。ホストにポートを公開するものではありません。
プロキシネットワークを内部専用にできますか?
プロキシとルーティングの設計に必要な受信経路と送信経路が確保される場合に限り可能です。内部ネットワークでは、接続されたコンテナの通常の外部接続が遮断されるため、証明書やID関連のフローが壊れる可能性があります。
コンテナIPアドレスではなくサービス名を使うのはなぜですか?
コンテナのアドレスは再作成後に変わる可能性があります。Dockerのサービスディスカバリは共有ネットワーク内で安定した名前を提供するため、プロキシ設定の耐久性が高まります。
保存したベースラインを復元し、承認済みの設定を一度だけ適用し、本番に近い元の負荷を再現して、約束された成功シグナルを確認してから、文書化されたロールバックを実行します。ログ、所要時間、権限、容量、復旧した出力がすべて受け入れ基準と一致するまで、変更を完了しないでください。
サポートとヒント
もっと読む

セルフホスト型ギャラリーでApple Live Photoのペアリングを保持できますか?
Apple Live Photoのペアリングに関する条件付きホームサーバー判断ガイド。管理されたテスト、結果の解釈、ロールバック、そして要点を絞ったFAQを含みます。

Google Takeoutとスマートフォンのバックアップを1つの写真ライブラリに取り込めますか?
写真の一括取り込みに関する条件付きホームサーバーの判断、管理されたテスト、結果の解釈、ロールバック、要点を絞ったFAQ。

Immichはファイルの所有権を取得せずに外部ライブラリを使用できますか?
Immichの外部ライブラリ所有権に関する条件付きホームサーバー判断ガイド。管理されたテスト、結果の解釈、ロールバック、要点を絞ったFAQを含みます。

