Apache VirtualHost로 Discourse를 실행하는 방법

서버에 Discourse를 성공적으로 설치하고, 첫 번째 사용자로 등록했으며, 첫 번째 주제를 게시했습니다. 따라서 Discourse 측에서는 모든 것이 정상적으로 작동하는 것으로 보입니다.

하지만 Discourse를 설치하고 실행하기 위해 Apache httpd 데몬을 비활성화해야 했습니다. 이는 저에게 큰 문제입니다. 왜냐하면 저의 웹사이트 여러 개와 Jitsi 회의 서버를 포함하여 웹 서버 전체를 기본적으로 종료한 상태이기 때문입니다.

제 Jitsi 설치 환경은 호스팅 중인 웹사이트 중 하나의 서브도메인을 사용하여 별도의 가상 호스트로 실행됩니다. Jitsi는 다른 웹 트래픽과 포트 443을 공유할 수 있으므로, Discourse도 같은 방식으로 구성하고 싶습니다.

Discourse 서브도메인으로 트래픽이 들어올 때 해당 트래픽을 Discourse로 전달하도록 허용하는 가상 호스트 정의 템플릿을 가지고 계신 분이 있을까요?

네, 메타에 다른 사이트와 함께 Discourse를 실행하는 방법에 대해 논의하는 가이드가 있습니다.

검색을 잘 활용하면 해당 가이드를 쉽게 찾을 수 있을 것입니다.

결론적으로 해결은 되었지만, 페이지가 완전히 로드된 것처럼 보여도 홈페이지가 요청을 완료하는 데 여전히 시간이 오래 걸리는 것 같습니다. (이것이 정상적인 동작인지 아닌지 확신이 서지 않습니다.)

Discourse
/var/discourse/containers/app.yml 파일의 expose 블록을 다음과 같이 수정했습니다.

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

이 설정은 로컬호스트에서 Docker 컨테이너로 트래픽을 전달합니다. 이 작업을 수행한 후에는 ./launcher rebuild app 명령을 사용하여 재빌드가 필요합니다.

Apache2 2.4.43 (Ubuntu)
서브도메인용 새로운 가상 호스트를 sites-available에 discourse.<myDomain>.com.conf 파일로 추가하여, 서브도메인의 트래픽을 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 님, 안녕하세요.

문제를 해결하셨다는 소식을 접해 반갑습니다.

저는 여러 서버에서 Apache2를 프론트 엔드 리버스 프록시로 사용하여 유닉스 소켓을 통해 디스코어를 실행하고 있습니다. 설정은 잘 작동합니다(모두 아시다시피 nginx보다 약간 느리지만, 일부 서버에서는 nginx를 사용하고 있으며, 이 설정에서는 잘 작동합니다).

기본적으로 가상 호스트를 다음과 같이 설정합니다:

포트 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. 이 설정에서는 항상 유닉스 소켓을 통해 디스코어 컨테이너를 노출(expose)하며, TCP/IP 컨테이너 포트를 노출하지 않습니다.

감사합니다. 늦게나마 도움이 되길 바랍니다.

빠른 추가 사항 두 가지입니다:

  1. 직접 프록시 대신 유닉스 소켓을 사용하려면 app.yml에서 web.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>

Apache가 /var/discourse에서 위와 같이 읽도록 하려면 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에는 Let’s Encrypt 인증서를 자동으로 발급받아 주는 상당히 유용한 mod_md 모듈이 있습니다. 적극 권장합니다.