DiscourseをApacheのVirtualHostとして実行する方法

Discourse をサーバーに正常にインストールし、最初のユーザーとして登録し、最初のトピックを投稿することができました。Discourse 側の動作はすべて問題なさそうです。

ただし、Discourse のインストールと起動を行うために、Apache httpd デーモンを無効にする必要がありました。これは私にとって大きな問題です。複数のドメインや Jitsi 会議サーバーを含む、ほぼすべてのウェブサーバーを停止することになったためです。

私の Jitsi インストールは、ホストしているウェブサイトのサブドメインを使用した別々の仮想ホストとして動作しています。Jitsi は他のウェブトラフィックとポート 443 を共有できるため、Discourse でも同じことを実現したいと考えています。

Discourse のサブドメインで受信したトラフィックを Discourse に転送するための仮想ホスト定義のテンプレートをご存知の方はいらっしゃいますか?

はい、Meta には Discourse を他のサイトと一緒に運用する方法について論じているガイドがあります。

検索を使えば、それらを見つけられると確信しています。

実質的には解決しましたが、ホームページの要求が完了するまでに非常に時間がかかり、ページが完全に読み込まれた後もその状態が続いています。(これが通常の動作なのかどうかわかりません。)

Discourse
/var/discourse/containers/app.yml 内の expose ブロックを以下のように変更しました。

expose:
  - "127.0.0.1:8000:80"   # http
  - "127.0.0.1:8443:443"  # https

これにより、localhost から Docker コンテナへポートフォワーディングが行われます。この変更後、./launcher rebuild app を実行して再構築を行う必要があります。

Apache2 2.4.43 (Ubuntu)
サブドメイン用の新しいバーチャルホスト discourse.<myDomain>.com.conf を sites-available に追加し、サブドメインのトラフィックを Discourse の Docker インスタンスがリッスンしている localhost のポートへ転送するように設定しました。バーチャルホストの定義は以下の通りです。

<VirtualHost *:80>
    ServerName discourse.<myDomain>.com
    Redirect permanent / https://discourse.<myDomain>.com/
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

<VirtualHost *:443>

  ServerName discourse.<myDomain>.com

  SSLProtocol TLSv1 TLSv1.1 TLSv1.2
  SSLEngine on
  SSLProxyEngine on
  SSLCertificateFile /etc/letsencrypt/live/<myDomain>.com/cert.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/<myDomain>.com/privkey.pem
  SSLCACertificateFile /etc/letsencrypt/live/<myDomain>.com/chain.pem
  SSLCipherSuite "EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA256:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EDH+aRSA+AESGCM:EDH+aRSA+SHA256:EDH+aRSA:EECDH:!aNULL:!eNULL:!MEDIUM:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4:!SEED"
  SSLHonorCipherOrder on
  Header set Strict-Transport-Security "max-age=31536000"

  <Location />
    Order allow,deny
    Allow from all
    Require all granted
  </Location>

  ProxyPreserveHost on
  ProxyRequests Off
  RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}
  RequestHeader set X-Real-IP expr=%{REMOTE_ADDR}
  ProxyPass / https://127.0.0.1:8443/
  ProxyPassReverse / https://127.0.0.1:8443/

</VirtualHost>

Apacheの設定にあまり時間を割いていないため、不要な行や追加・改善可能な行があるかもしれません。フィードバックを歓迎します。

Nap さん、こんにちは。

問題が解決したと聞いて嬉しいです。

私は複数のサーバーで Discourse を運用しており、フロントエンドのリバースプロキシとして Apache2 を使用して Unix ソケットに接続しています。この設定は問題なく動作しています(ご存知の通り、nginx に比べると少し遅いですが、私も一部のサーバーで nginx を運用しており、Apache2 でも十分動作します)。

基本的には、以下のように仮想ホストを設定しています。

ポート 80 の設定

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName  discourse.mygreatwebsite.com
    DocumentRoot /website/discourse  # 多くの場合不要

    RewriteEngine On
    ProxyPreserveHost On
    ProxyRequests Off
    ErrorLog /var/log/apache2/discourse.error.log
    LogLevel warn
    CustomLog /var/log/apache2/discourse.access.log combined

    RewriteCond %{SERVER_NAME} =discourse.mygreatwebsite.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

ポート 443 の設定:

<VirtualHost *:443>
  ServerAdmin webmaster@localhost
  ServerName  discourse.mygreatwebsite.com
  DocumentRoot /website/nginx  # この設定ではほとんど不要
  
  SSLProxyEngine on
  RewriteEngine On
  ProxyPreserveHost On
  ProxyRequests Off
  RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}
  RequestHeader set X-Real-IP expr=%{REMOTE_ADDR}
  
  ProxyPass / unix:/var/discourse/shared/socket-only/discourse.http.sock|http://my.ip.address.here/
  ProxyPassReverse  / unix:/var/discourse/shared/socket-only/discourse.http.sock|http://my.ip.address.here/
  ErrorLog /var/log/apache2/discourse-ssl.error.log
  LogLevel warn
  CustomLog /var/log/apache2/discourse-ssl.access.log combined

  Include /etc/letsencrypt/options-ssl-apache.conf
  SSLCertificateFile /etc/letsencrypt/live/discourse.com/fullchain.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/discourse.com/privkey.pem
</VirtualHost>

注記:

  1. 通常、SSL 証明書の設定やリダイレクトなどは letsecrypt certbot に任せています。

  2. Apache2 の設定ファイルでは、Apache2 がバインドされている IP アドレスを使用しています。

  3. この設定では、Discourse コンテナ内の Unix ソケットを常に設定(公開)し、TCP/IP コンテナポートは公開していません。

遅くなりましたが、参考になれば幸いです。

では。

2 つの簡単な追加事項:

  1. 直接プロキシの代わりに Unix ソケットを使用したい場合は、app.ymlweb.socketed.template.yml を有効にした後、以下のように設定できます:
  ProxyPreserveHost On
  ProxyRequests Off
  RequestHeader set X-Forwarded-Proto https
  RequestHeader set X-Real-IP expr=%{REMOTE_ADDR}
  <Location />
    ProxyPass unix:/var/discourse/shared/standalone/nginx.http.sock|http://localhost/
    ProxyPassReverse unix:/var/discourse/shared/standalone/nginx.http.sock|http://localhost/
  </Location>

なお、このように /var/discourse から Apache が読み込むように設定すると、SELinux の対応が必要になる可能性があります。その場合は、semanage fcontext -a -t httpd_sys_rw_content_t /var/discourse/shared/standalone/nginx.http.sock を実行し、続けて restorecon /var/discourse/shared/standalone/nginx.http.sock を実行すれば対応できるはずです。

  1. Apache には、LetsEncrypt の証明書を自動的に取得できる非常に優れた mod_md というモジュールがあります。強くお勧めします。