単一のVPS上でNginxリバースプロキシを使ってDiscourseとWordPressをDockerで動かす

はじめに

デフォルトでは、Discourse の「スタンドアロン」インストールはポート 80 および 443 にバインドされます。同じサーバー上で WordPress などの別のアプリケーションをホストするには、Discourse を内部ポートでリッスンするように再構成し、ホストレベルの Nginx をリバースプロキシとして使用してトラフィックと SSL 証明書を管理する必要があります。


1. アーキテクチャの概要

  • ホスト Nginx: ポート 80 および 443 でリッスンするプライマリゲートウェイ。SSL 終端を処理し、server_name に基づいてリクエストを適切なコンテナにルーティングします。

  • Discourse コンテナ: localhost:8080 でリッスンするように再構成されます。

  • WordPress コンテナ: Docker Compose 経由で管理され、localhost:8081 でリッスンします。


2. フェーズ A: Discourse の再構成

/var/discourse/containers/app.yml を変更して、パブリックポートを解放します。

  1. ポートマッピングの変更:

    YAML

    expose:
      - "8080:80"   # ホストポート 8080 をコンテナポート 80 にマッピング
    
    
  2. 内部 SSL の無効化: SSL および Let’s Encrypt テンプレートをコメントアウトします。

    YAML

    templates:
      - "templates/postgres.template.yml"
      - "templates/redis.template.yml"
      - "templates/web.template.yml"
      # - "templates/web.ssl.template.yml"
      # - "templates/web.letsencrypt.ssl.template.yml"
    
    
  3. 再構築: ./launcher rebuild app を実行します。


3. フェーズ B: Docker Compose による WordPress のデプロイ

WordPress サイトを専用のディレクトリに整理します。データ損失を防ぐために、データベースボリュームが永続的であることを確認してください。

YAML

services:
  db:
    image: mariadb:10.11
    environment:
      MYSQL_ROOT_PASSWORD: 'your_secure_password'
    volumes:
      - ./mysql_data:/var/lib/mysql
  wordpress:
    image: wordpress:latest
    ports:
      - "8081:80"
    volumes:
      - .:/var/www/html


4. フェーズ C: 最終的な Nginx 設定 (SSL およびポート 443)

2025 年のプロフェッショナルなセットアップには、完全な HTTPS および HTTP/2 サポートが必要です。ホストに Nginx をインストールした後 (sudo apt install nginx)、ドメインの構成を作成します。

プロのヒント: sudo certbot --nginx を実行して SSL ブロックを自動生成しますが、Discourse が正しく機能するように、以下のプロキシヘッダーが含まれていることを確認してください。

Nginx

server {
    listen 443 ssl http2;
    server_name discourse.com;

    # Certbot による SSL 証明書
    ssl_certificate /etc/letsencrypt/live/discourse.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/discourse.com/privkey.pem;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme; # Discourse の HTTPS 検出に不可欠
    }
}


5. 苦労して得た教訓とベストプラクティス

  • データベース認証情報: パスワードに &? などの特殊文字が含まれている場合は、シェルによる解釈エラーを防ぐため、設定ファイルやターミナルコマンドでは必ずシングルクォート ' ' で囲んでください。

  • ファイルパーミッション: WordPress コンテナは www-data (UID 33) として実行されます。root としてファイルをアップロードまたは解凍した場合、500 Internal Server Error を回避するには chown -R 33:33 . を実行する必要があります。

  • Cloudflare 設定: サーバー上の SSL 証明書 (Let’s Encrypt) を使用する場合、Cloudflare の SSL/TLS を Full (Strict) に設定します。「Flexible」モードによって一般的に引き起こされる「リダイレクトが多すぎる」ループを防ぎます。

  • 永続ボリューム: データベースファイルが永続ボリューム (例: ./mysql_data) に保存されていることを確認せずに、docker compose downrebuild を実行しないでください。


結論: リバースプロキシを使用してアプリをポート 80/443 から分離することは、マルチサイト VPS を管理するための最もスケーラブルな方法です。これにより、SSL の一元管理と、ホストレベルの Nginx ログを介した簡単なデバッグが可能になります。

「いいね!」 2