Skip to content

006: サービスポート設定のリファクタリング

コンテキスト (Context)

本プロジェクトの初期実装では、サービスポートが複数の場所にハードコードされていました:docker-compose.ymlnginx.confDockerfile (EXPOSE)、およびアプリケーション固有の設定ファイル(50-server.cnfwww.conf)。

このアプローチにはいくつかの課題がありました:

  1. 柔軟性: ポートを変更するには複数のファイルを編集する必要がありました。
  2. 環境の独立性: 複数のインスタンスを実行したり、ホストマシン上のポート衝突を回避したりすることが困難でした。
  3. 冗長性: ポート番号が設定ファイル間で繰り返されており、不整合が生じる可能性がありました。
  4. リダイレクトループ: .env 経由でパブリックポートを変更(例:443から8443へ)しても、WordPressが適切に設定されていないとデフォルトのポートへリダイレクトしてしまい、アクセス問題が発生していました。

決定 (Decision)

ポート設定を完全に動的にし、.env ファイルで定義された環境変数によって制御されるようにリファクタリングすることを決定しました。

主な変更点 (Key Changes)

  1. 環境変数: .envNGINX_PORTMARIADB_PORTWP_PORT を導入しました。
  2. Dockerfile ARG & EXPOSE:
    • Nginx、MariaDB、WordPressのDockerfileを更新し、ポート番号をビルド引数 (ARG) として受け取るようにしました。
    • EXPOSE ${PORT_VAR} を使用して、イメージメタデータ内の公開ポートを動的にドキュメント化しました。
    • これらの引数を docker-compose.yml 経由で渡すようにしました。
  3. 実行時の設定注入 (Runtime Configuration Injection):
    • Nginx: entrypoint.shenvsubst を使用し、実行時にテンプレートから nginx.conf を生成するようにしました。
    • MariaDB/WordPress: それぞれの起動スクリプト(initial_db.sh, setup.sh)で sed を使用し、サービス開始前に設定ファイル(50-server.cnf, www.conf)へ設定されたポートを注入するようにしました。
  4. WordPressサイトURLロジック:
    • 非標準ポート使用時のリダイレクトループを防ぐため、WordPressサイトURL生成時に NGINX_PORT を使用するように setup.sh を更新しました。

結果 (Consequences)

メリット (Pros)

  • 信頼できる唯一の情報源 (Single Source of Truth): すべてのポート設定が .env で管理されます。
  • 変更の容易さ: ポート変更(例:Nginxを8443へ)は、.env の更新と docker compose up --build の実行だけで済みます。
  • 整合性: Dockerイメージ内の EXPOSE 命令が実際の設定と一致します。

デメリット (Cons)

  • ビルドへの依存: .env でポート変数を変更した場合、イメージ内の EXPOSE メタデータを更新するためにリビルド(--build)が必要になります(ただし、実行時設定注入があるため、技術的にはリビルドなしでもサービスは動作します)。
  • 複雑性: Dockerfileや docker-compose.yml に間接的な層(ARG渡し)が追加されました。

実装の詳細 (Detailed Implementation)

Dockerfileパターン

EXPOSE が環境変数を尊重するように、以下のパターンを採用しました:

dockerfile
# Dockerfile
ARG SERVICE_PORT=default_value
EXPOSE ${SERVICE_PORT}
yaml
# docker-compose.yml
services:
  myservice:
    build:
      args:
        SERVICE_PORT: ${SERVICE_PORT}

ボーナス: WebsiteサービスのコールバックURL設定

Website サービス (Node.js/Express) では、OAuthコールバックURLが当初ハードコードされているか、デフォルトの443ポートになっていました。 NGINX_PORT が変更された場合(例:8443へ)、OAuth APIへ送信されるコールバックURLもこの変更を反映する必要があり、そうでないと認証後のリダイレクトに失敗します。

NGINX_PORT を使用して callbackURL を動的に構築するように server.js を更新しました:

javascript
const NGINX_PORT = process.env.NGINX_PORT || 443;
const portSuffix = (NGINX_PORT == 443) ? '' : `:${NGINX_PORT}`;
const callbackURL = `https://${DOMAIN_NAME}${portSuffix}${BASE_URL}/auth/42/callback`;

これにより、.env で設定されたポートに関わらず、認証フローが正しく動作することが保証されます。

Released under the MIT License.