Apache와 프록시 리다이렉트 사용 시 Discourse가 로드되지 않음

지난 며칠 동안 DigitalOcean 드롭렛에서 Discourse와 Apache를 함께 실행하는 방법을 찾고 있었지만, Discourse에 있는 튜토리얼들은 모두 오래되었거나 제 환경에 맞지 않았습니다. 한 튜토리얼은 CentOS와 HAProxy를 사용했고(저는 Ubuntu를 사용 중), 다른 하나는 Nginx를 사용했습니다(저는 Apache를 사용 중).

DigitalOcean 스레드에서 한 댓글을 발견하고 테스트 드롭렛에서 해당 지시를 따랐습니다: Install Discourse on a droplet with WordPress served by Apache ? | DigitalOcean

Let’s Encrypt SSL 포함하여 모든 과정이 순조롭게 진행되었습니다. 정적 HTML 문서인 제 홈페이지도 정상적으로 작동합니다. Discourse는 오류 없이 설치되었지만, 화면에 표시되지 않습니다. community.mysite.com으로 이동하면 URL에 보안되지 않은 HTTPS가 표시된 제 홈페이지만 보입니다. 네임서버(DNS) 설정은 정확하며 올바른 서버를 가리키고 있습니다.

제 mysite.com.conf 파일은 다음과 같습니다:

<VirtualHost *:80>
	ServerAdmin webmaster@localhost
	ServerName mysite.com
	ServerAlias www.mysite.com
	DocumentRoot /var/www/mysite.com
	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =www.mysite.com [OR]
RewriteCond %{SERVER_NAME} =mysite.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

제 mysite.com-le-ssl.conf 파일은 다음과 같습니다:

<IfModule mod_ssl.c>
<VirtualHost *:443>
	ServerAdmin webmaster@localhost
	ServerName mysite.com
	ServerAlias www.mysite.com
	DocumentRoot /var/www/mysite.com
	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

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

제 community.mysite.com.conf 파일은 다음과 같습니다:

<VirtualHost *:80>
  ServerName community.mysite.com
  ServerAlias www.community.mysite.com

  <IfModule proxy_module>
    ProxyPreserveHost on
    ProxyPass / http://localhost:8080/
    ProxyPassReverse / http://localhost:8080/
  </IfModule>
</VirtualHost>

마지막으로, 제 app.yml 파일(물론 편집된 상태)은 다음과 같습니다:

## this is the all-in-one, standalone Discourse Docker container template
##
## After making changes to this file, you MUST rebuild
## /var/discourse/launcher rebuild app
##
## BE *VERY* CAREFUL WHEN EDITING!
## YAML FILES ARE SUPER SUPER SENSITIVE TO MISTAKES IN WHITESPACE OR ALIGNMENT!
## visit http://www.yamllint.com/ to validate this file as needed

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Uncomment these two lines if you wish to add Lets Encrypt (https)
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"

## which TCP/IP ports should this container expose?
## If you want Discourse to share a port with another webserver like Apache or nginx,
## see https://meta.discourse.org/t/17247 for details
expose:
      - "8080:80"   # fwd host port 8080   to container port 80 (http)
      - "8443:443"   # fwd host port 8443 to container port 443 (http)

params:
  db_default_text_search_config: "pg_catalog.english"

  ## Set db_shared_buffers to a max of 25% of the total memory.
  ## will be set automatically by bootstrap based on detected RAM, or you can override
  db_shared_buffers: "128MB"

  ## can improve sorting performance, but adds memory usage per-connection
  #db_work_mem: "40MB"

  ## Which Git revision should this container use? (default: tests-passed)
  #version: tests-passed

env:
  LANG: en_US.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

  ## How many concurrent web requests are supported? Depends on memory and CPU cores.
  ## will be set automatically by bootstrap based on detected CPUs, or you can override
  UNICORN_WORKERS: 2

  ## TODO: The domain name this Discourse instance will respond to
  ## Required. Discourse will not work with a bare IP number.
  DISCOURSE_HOSTNAME: community.mysite.com

  ## Uncomment if you want the container to be started with the same
  ## hostname (-h option) as specified above (default "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: List of comma delimited emails that will be made admin and developer
  ## on initial signup example 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'myemail'

  ## TODO: The SMTP mail server used to validate new accounts and send notifications
  # SMTP ADDRESS, username, and password are required
  # WARNING the char '#' in SMTP password can cause problems!
  DISCOURSE_SMTP_ADDRESS: smtp.mailgun.org
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: my-smtp-username
  DISCOURSE_SMTP_PASSWORD: "my-smtp-password"
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (optional, default true)

  ## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate
  LETSENCRYPT_ACCOUNT_EMAIL: myemail

  ## The http or https CDN address for this Discourse instance (configured to pull)
  ## see https://meta.discourse.org/t/14857 for details
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

## The Docker container is stateless; all data is stored in /shared
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## Plugins go here
## see https://meta.discourse.org/t/19157 for details
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## Any custom commands to run after building
run:
  - exec: echo "Beginning of custom commands"
  ## If you want to set the 'From' email address for your first registration, uncomment and change:
  ## After getting the first signup email, re-comment the line. It only needs to run once.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "End of custom commands"

제가 어디에서 실수를 했는지, 혹은 무엇을 놓치고 있는지 알려주실 수 있을까요? 감사합니다!

nginx를 리버스 프록시로 사용해 보는 것이 훨씬 더 좋은 결과를 얻을 수 있습니다.

시스템이 허용한다면, apache2 대신 nginx를 사용하는 것을 고려해 보세요.

그러면 community가 도메인으로 리다이렉트되는 대신 IP를 가리키는 것이 맞나요? /etc/apache2/sites-enabled/에 심볼릭 링크가 존재하나요?

proxy_module이 로드되어 있나요?
apache2ctl -M

심볼릭 링크가 없습니다.

네. 다행히도 제가 링크한 튜토리얼의 단계 중 하나입니다.

a2enmod proxy
a2enmod proxy_http
a2enmod proxy_balancer
a2enmod lbmethod_byrequests

다음 단계

a2ensite community.yoursite.com

이 제대로 수행되지 않았을 수 있으며, sudo가 필요할 수 있습니다.

sudo ln -s /etc/apache2/sites-available/community.yoursite.com.conf /etc/apache2/sites-enabled/

을 사용하면 됩니다.
그 후

sudo apachectl configtest

을 실행하고, 기원하며

sudo systemctl restart apache2

을 실행하세요.

Dear @OrbitStorm,

I took a quick look at your Apache2 virtual hosts configuration for you and your yml file for Discourse and they do not appear to be correctly configured.

Here are some hints:

First of all, when you run Discourse behind a reverse proxy, you do not enable SSL LETSENCRYPT in the Discourse yml configuration (see working example below). Discourse only needs a single port to communicate with the reverse proxy and that is not an SSL encrypted connection.

Second, if you look at your main virtual host configuration, which is the port 443 on the reverse proxy:

<IfModule mod_ssl.c>
<VirtualHost *:443>
	ServerAdmin webmaster@localhost
	ServerName mysite.com
	ServerAlias www.mysite.com
	DocumentRoot /var/www/mysite.com
	ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined

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

That configuration above is missing all necessary reverse proxy information (see attached working configurations below).

Here is a working configuration for you, which is basically the same as outlined in the various tutorials on meta (well documented on this site in other posts, so this is basically duplicating other documentation here at meta):

<VirtualHost *:80>
        ServerName discourse.your-great-web-site.com
        ServerAdmin webmaster@localhost
        ProxyPreserveHost On
        ErrorLog ${APACHE_LOG_DIR}/discourse_errors.log
        CustomLog ${APACHE_LOG_DIR}/discourse.log combined
        ModPagespeed Off
        RewriteEngine on
        RewriteCond %{SERVER_NAME} =discourse.your-great-web-site.com
        RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

Note that in the port 80 configuration, there is the main required directives are the ServerName, RewriteEngine and rewrite rules to redirect to port 443.

Also, if you are running Apache2 mod_pagespeed you should disable as I have not yet got mod_pagespeed working with Discourse (and see no reason to do so either).

Here is the main config, where the “real-work” is done:

<IfModule mod_ssl.c>
<VirtualHost *:443>
        ServerName discourse.your-great-web-site.com
        ServerAdmin webmaster@localhost
        SSLProxyEngine on      # enable this only after let's encrypt is configured and working
  	    RewriteEngine on
  	    ProxyPreserveHost On
  	    ProxyRequests Off
  	    RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}
 	    RequestHeader set X-Real-IP expr=%{REMOTE_ADDR}

        #ProxyPass / http://127.0.0.1:8888/           # we do not use port, we use your-great-web-site sockets
        #ProxyPassReverse / http://127.0.0.1:8888/    # we do not use port, we use your-great-web-site sockets
        ProxyPass / your-great-web-site:/var/discourse/shared/socket-only/nginx.http.sock|http://localhost/
        ProxyPassReverse  / your-great-web-site:/var/discourse/shared/socket-only/nginx.http.sock|http://localhost/

        ErrorLog ${APACHE_LOG_DIR}/discourse_errors_ssl.log
        #CustomLog ${APACHE_LOG_DIR}/discourse_ssl.log combined   #access log disabled for production

        ModPagespeed Off
        SSLCertificateFile /etc/letsencrypt/live/discourse.your-great-web-site.com/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/discourse.your-great-web-site.com/privkey.pem
        Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

All our discourse configurations use unix domain sockets, so you will need to change the configuration to match your desired configuration.

The main point to understand (in summary), is that you should disable LETSENCRYPT in your Discourse build (yml) configuration and only expose a single entry point into Discourse, in our case a unix domain socket, in your case a single TCP/IP socket.

Then you reverse proxy to that entry point from the virtual host file for port 443 (not from the port 80 virtual host). The port 80 virtual host simply redirects to 443. Your 443 SSL is all done by LETSENCRYPT in the reverse proxy. There is no SSL required in your Discourse yml file (see working example below).

Here is one of our working yml files (for the configuration above) for you to review:

/var/discourse/containers$ cat socket-only.yml
# IMPORTANT: SET A SECRET PASSWORD in Postgres for the Discourse User
# TODO: change SOME_SECRET in this template

templates:
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
  - "templates/web.socketed.template.yml"
#  - "templates/sshd.template.yml"
## Uncomment these two lines if you wish to add Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"

## which TCP/IP ports should this container expose?
## If you want Discourse to share a port with another webserver like Apache or nginx,
## see https://meta.discourse.org/t/17247 for details
expose:
#  - "80:80"   # http
#  - "443:443" # https

# Use 'links' key to link containers together, aka use Docker --link flag.
links:
  - link:
      name: data
      alias: data

# any extra arguments for Docker?
# docker_args:

params:
  ## Which Git revision should this container use? (default: tests-passed)
  #version: latest
  db_shared_buffers: "4GB"

env:
  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8

  # DISCOURSE_DEFAULT_LOCALE: en

  ## How many concurrent web requests are supported? Depends on memory and CPU cores.
  ## will be set automatically by bootstrap based on detected CPUs, or you can override
  #UNICORN_WORKERS: 3
  UNICORN_WORKERS: 8

  ## TODO: The domain name this Discourse instance will respond to
  DISCOURSE_HOSTNAME: 'discourse.your-great-web-site.com'

  ## Uncomment if you want the container to be started with the same
  ## hostname (-h option) as specified above (default "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: List of comma delimited emails that will be made admin and developer
  ## on initial signup example 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'tim@discourse.your-great-web-site.com'

  ## TODO: The SMTP mail server used to validate new accounts and send notifications
  # SMTP ADDRESS, username, and password are required
  # WARNING the char '#' in SMTP password can cause problems!
  DISCOURSE_SMTP_ADDRESS: smtp.gmail.com
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: not_for_reply@discourse.your-great-web-site.com
  DISCOURSE_SMTP_PASSWORD: my_super_secret_cool_password
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (optional, default true)

  ## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate
  #LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  ## TODO: configure connectivity to the databases
  DISCOURSE_DB_SOCKET: ''
  #DISCOURSE_DB_USERNAME: discourse
  DISCOURSE_DB_PASSWORD: another_super_secret_cool_password
  DISCOURSE_DB_HOST: data
  DISCOURSE_REDIS_HOST: data

  DISCOURSE_MAXMIND_LICENSE_KEY: my_max_mind_key
  ## The http or https CDN address for this Discourse instance (configured to pull)
  ## see https://meta.discourse.org/t/14857 for details
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com

volumes:
  - volume:
      host: /var/discourse/shared/socket-only
      guest: /shared
  - volume:
      host: /var/discourse/shared/socket-only/log/var-log
      guest: /var/log

## Plugins go here
## see https://meta.discourse.org/t/19157 for details
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
          - git clone https://github.com/discourse/discourse-bbcode.git
          - git clone https://github.com/discourse/discourse-sitemap.git
          - git clone https://github.com/discourse/discourse-solved.git
          - git clone https://github.com/discourse/discourse-whos-online.git
          - git clone https://github.com/unixneo/legacy-info.git

## Remember, this is YAML syntax - you can only have one block with a name
run:
  - exec: echo "Beginning of custom commands"

  ## If you want to configure password login for root, uncomment and change:
  ## Use only one of the following lines:
  #- exec: /usr/sbin/usermod -p 'PASSWORD_HASH' root
  #- exec: /usr/sbin/usermod -p "$(mkpasswd -m sha-256 'RAW_PASSWORD')" root

  ## If you want to authorized additional users, uncomment and change:
  #- exec: ssh-import-id username
  #- exec: ssh-import-id anotherusername

  - exec: echo "End of custom commands"
  #- exec: awk -F\# '{print $1;}' ~/.ssh/authorized_keys | awk 'BEGIN { print "Authorized SSH keys for this container:"; } NF>=2 {print $NF;}'

It’s really easy once you understand the basics; and understanding the basics does help quite a lot :slight_smile:

Please keep in mind that in our Discourse configurations, we do not run a single container (actually, we rarely run in single container mode), so our yml file will not work in a single container (standalone) configuration. I am providing it to you for reference to help you, by showing you what a fully working configuration behind Apache2 looks like.

We run Discourse behind both Apache2 and nginx reverse proxies. In fact, we only use reverse proxies for many reasons. One reason is that we can use the reverse proxy to filter bad bots, etc (a totally different subject).

There is nothing difficult about running Dockerized Discourse (as many sites as you want, one or 100) behind a reverse proxy on a site with Apache2; but it does help to understand the basic concepts.

I hope providing you both the basic concepts and working example configuration files help you move forward and get Discourse up and running.

Best Regards…

@neounix 정말 깊이 있는 답변을 주셔서 감사드립니다. 하지만 제가 겪고 있는 문제 대부분은 적합한 최신 튜토리얼을 찾지 못해서인 것 같습니다. 여기 있는 여러 튜토리얼에서는 yml 파일에서 Discourse의 SSL을 활성화하라고 안내하고, 그중 하나는 Let’s Encrypt가 자동으로 처리하기 때문에 VirtualHost 파일에 프록시 정보를 추가할 필요가 없다고 말합니다. 그런데 당신의 예제는 제 기본 설정과도 완전히 달라서 CentOS 설정을 Ubuntu와 혼합하는 것처럼 혼란스럽기만 합니다.

기본적인 이해가 큰 도움이 된다는 말씀에 전적으로 동의합니다. 하지만 문제는 기초가 제대로 다루어지지 않고 있고, 다루어져 있더라도 3년 전의 오래된 내용이며, Nginx 대신 Apache를 사용하거나 CentOS 대신 Ubuntu를 사용하는 사용자를 전혀 고려하지 않고 있다는 점입니다. 또한 Discourse가 Docker를 사용할 수 있는 유일한 이유라는 점도 언급할 가치가 있습니다.

Apache와 함께 애플리케이션을 설치하기만 하려고 4일을 허비한 끝에, 저는 포기했습니다. 무료든 아니든, 이 정도 두통을 감수할 가치가 없다고 생각합니다. 더 이상 포럼을 뒤져서 똑같은 오래된이고 불완전한 두 개의 튜토리얼에 대한 복사/붙여넣기 링크만 발견할 수는 없습니다. Discourse를 만나기 전까지는 포럼 소프트웨어를 설치하는 것이 이렇게 답답한 경험은 처음이었습니다. 이 말은 많은 것을 말해줍니다. XenForo와 Invision은 제가 막대한 경험을 가진 두 플랫폼인데, 설치와 사용이 매우 쉽습니다.

진심으로 답변에 쏟으신 노력에 감사드립니다. 하지만 당신에게 제 일을 대신해 달라고 요청하지는 않을 것이며, 적절한 문서가 있었다면 제가 그렇게 해야 할 필요도 없었을 것입니다. 제 구체적인 상황은 그렇게 특별한 것이 아닌데, 신규 사용자에게 이 과정을 더 쉽게 만들어 줄 새로운 튜토리얼에서 이 상황이 강조되지 않은 것이 정말 놀랍습니다.

어쨌든, 좋은 결과 있으시길 바랍니다.

CentOS/Nginx에 지나치게 집중된 최신 문서가 전무하다는 점을 감안하여 Discourse를 떠날 의향이 있었음에도, DigitalOcean에서 한 매우 관대하고 인내심 있는 분이 제가 거기에 만든 스레드에 응답하여, 시행착오 끝에 저와 같은 상황에 처한 잠재적 Discourse 사용자를 위한 쉽게 따라 할 수 있는 튜토리얼을 작성하는 데 도움을 주었습니다.

참고로, 해당 상황은 다음과 같습니다:

Apache와 동일한 서버에 Discourse 설치 | Ubuntu 18.04 사용 | DigitalOcean

Bobbyiliev @ DigitalOcean에 감사드립니다
Install Discourse on a droplet with WordPress served by Apache ? | DigitalOcean (첫 번째 답변)

사전 요구 사항

  • 안전을 위해 Droplet을 백업하여, 문제가 발생했을 경우 작동하는 버전으로 되돌릴 수 있도록 하세요.
  • Droplet에 SSH로 접속하세요.
  • Apache가 설치되어 있어야 합니다. 설치 방법은 다음 링크의 단계를 따르세요:

1단계 - Docker 설치

Docker를 설치하려면 다음 링크의 단계를 따르세요:

2단계 - Discourse 다운로드

먼저 Discourse 파일을 저장할 디렉터리를 생성하세요:

mkdir /var/discourse

이후 공식 Discourse Docker 이미지를 /var/discourse로 클론하세요.

git clone https://github.com/discourse/discourse_docker.git /var/discourse

3단계 - Discourse가 8080 포트를 경청하도록 설정

PostgreSQL, Redis 등 필요한 모든 서비스를 포함하고 있는 standalone.yml 템플릿을 사용할 것입니다.

다음 명령어로 샘플 파일을 복사하세요:

cp /var/discourse/samples/standalone.yml /var/discourse/containers/app.yml

이후 선호하는 편집기로 파일을 편집하세요. /var/discourse/containers/app.yml 파일을 열고 23번과 24번 줄의 포트를 업데이트하세요:

## which TCP/IP ports should this container expose?
expose:
  - "8080:80"   # fwd host port 8080   to container port 80 (http)
  - "8443:443"   # fwd host port 8443 to container port 443 (http)

아직 SSL 인증서가 없다면 16번 줄을 주석 처리하도록 하세요:

  #- "templates/web.ssl.template.yml"

`- "templates/web.ssl.template.yml`` 줄 앞에 # 기호를 추가하세요. 그렇지 않으면 Discourse가 시작되지 않습니다.

4단계 - Discourse 설정

디렉터리 변경:

cd /var/discourse

그런 다음, Discourse를 시작하세요 (서비스를 처음 시작하는 것이므로 app.yml 파일에 있는 새로운 변경 사항으로 애플리케이션이 부트스트랩됩니다):

./discourse-setup

참고: 유효한 메일 서버 설정을 제공해야 합니다. 그렇지 않으면 설정이 실패할 수 있습니다.

5단계 - Apache 설정

/etc/apache2/sites-available/ 디렉터리에서 forum.example.com.conf라는 이름의 새 파일을 생성하고 다음 Vhost 내용을 추가하세요:

<VirtualHost *:80>
  ServerName forum.example.com
  ServerAlias www.forum.example.com

  <IfModule proxy_module>
    ProxyPreserveHost on
    ProxyPass / http://localhost:8080/
    ProxyPassReverse / http://localhost:8080/
  </IfModule>
</VirtualHost>
  • 다음 명령어로 Vhost를 활성화하세요:
a2ensite forum.example.com
  • Mod Proxy 활성화:
a2enmod proxy
a2enmod proxy_http
a2enmod proxy_balancer
a2enmod lbmethod_byrequests
  • Apache 재시작:
systemctl restart apache2

그 후 도메인 이름을 통해 Discourse에 직접 액세스할 수 있게 됩니다.


참고 1: Discourse를 설치할 때 app.yml이 덮어쓰여지고 16/17번 줄(SSL)의 주석이 해제될 수 있습니다. 해당 줄들을 다시 주석 처리한 후 앱을 재구성해야 합니다 (디렉터리 변경을 잊지 마세요): ./launcher rebuild app

참고 2: 이 가이드에서는 Discourse에 SSL이 활성화되지 않습니다. 놀랍게도, Apache에 이미 활성화되어 있는 경우 Let’s Encrypt SSL을 활성화하는 방법에 대한 문서가 존재하지 않는 것으로 보입니다. 이 문제에 대한 해결책을 발견하신 분은 연락 주시기 바랍니다.