# 권장(지원) 설치 방식으로 리버스 프록시 뒤에 Discourse 설치

**URL:** https://meta.discourse.org/t/installing-discourse-behind-reverse-proxy-using-recommended-supported-installation/300191
**Category:** Self-hosting
**Created:** [3월 20, 2024, 2:58오후 UTC](https://meta.discourse.org/t/installing-discourse-behind-reverse-proxy-using-recommended-supported-installation/300191 "2024-03-20T14:58:41Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![NullUsername](https://avatars.discourse-cdn.com/v4/letter/n/a183cd/32.png) [@NullUsername](https://meta.discourse.org/u/NullUsername)
#### Post date: [3월 20, 2024, 2:58오후 UTC](https://meta.discourse.org/t/installing-discourse-behind-reverse-proxy-using-recommended-supported-installation/300191/1 "2024-03-20T14:58:41Z")

</div>

이 게시물에서는 지원되는 설치 방법을 그대로 사용하면서 nginx 리버스 프록시 뒤에 discourse를 실행하는 방법을 정확히 보여드리겠습니다.

**요구 사항:**

1. 유효한 도메인 이름.
2. 유효한 SSL 인증서.
3. 해당 도메인 이름으로 가리키는 유효한 DNS 항목.
4. 정상 작동하는 이메일 서버 또는 SMTP 제공업체.
5. 정상 작동하는 Nginx 리버스 프록시 및 나중에 SSL 인증서를 생성하기 위해 인스턴스에 접근할 수 있는 능력.
6. docker를 실행할 수 있는 VM 또는 LxC 컨테이너.

이 가이드에서는 모든 기능이 작동하고, 백업, 업그레이드 등이 가능한 제 인스턴스를 예로 사용하겠습니다. 약 2주간 테스트했습니다.

**제 Discourse VM 사양:**

- CPU: 4코어
- RAM: 6GB
- Swap: 8GB (SSD 스왑 파일)
- 저장소: 50GB (SSD)
- OS: Ubuntu 22.04.3

테스트 시에는 최소 사양을 사용할 수 있습니다. Discourse는 기본적으로 2GB를 쉽게 초과하여 사용합니다. 비활성 상태에서의 사용량은 6GB 중 약 1.48GB입니다.

**참고:** 이 설치 방법은 리버스 프록시를 사용하여 SSL 인증서를 생성합니다. 원하시는 경우 certbot을 사용할 수도 있습니다.

**단계 1:**

[Get Ubuntu Server | Download | Ubuntu](https://ubuntu.com/download/server) 에서 최신 ubuntu 서버를 다운로드합니다.

**단계 2:**

1. VM/LxC 템플릿에 Ubuntu 서버를 설치합니다.  
1.1 모든 서버 패키지로 ubuntu가 최신 상태인지 확인합니다.
2. 다음 명령을 사용하여 필요한 모든 패키지를 설치합니다:

```plaintext
apt update -y && apt upgrade -y && apt wget curl zip git docker.io nginx -y && reboot

```

**단계 3:**  
Discourse 설치. 초보자 가이드 [discourse/docs/INSTALL-cloud.md at main · discourse/discourse · GitHub](https://github.com/discourse/discourse/blob/main/docs/INSTALL-cloud.md) 를 따릅니다.

서버에 ssh로 로그인하고 단순히 다음을 입력합니다:

```plaintext
sudo -s
git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
chmod 700 containers

```

위 내용을 완료한 후 `./discourse-setup`를 실행할 수 있습니다.

모든 단계를 따르고 올바르게 입력하십시오. 이는 성공적인 설치를 위해 매우 중요합니다.  
단계에서는 다음과 같은 내용을 묻습니다. 설치 가이드의 예시:

 ![discourse-setup](https://global.discourse-cdn.com/meta/original/4X/6/1/8/618b8c71f61c6719eb5dc3f826afe67f23357f1a.png)

설치를 실행 상태로 두십시오. 인터넷 연결과 서버 사양에 따라 시간이 걸릴 수 있습니다. 제 VM 설정을 사용하여 설치를 완전히 완료하는 데 약 5~8분이 걸렸습니다.

**단계 4:**

설치가 완료되면 docker 컨테이너가 사용하는 시작 명령과 생성된 컨테이너 ID(해시)를 볼 수 있습니다.

**참고:** WAN을 통해 프록시 뒤에 있으므로 502 오류가 표시되며 컨테이너가 dockers 네트워크를 사용하므로 WAN 또는 LAN에서 접근할 수 없습니다. `172.17.0.1/16` 네트워크에 연결하는 경우를 제외합니다. 이 네트워크는 필요하지 않습니다.

설치가 완료되었고 docker 컨테이너가 실행 중인지 다음을 사용하여 다시 확인하십시오:

```plaintext
docker ps

```

다음과 같은 출력을 받아야 합니다.

```plaintext
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
XXXXXX local_discourse/app "/sbin/boot" 6 days ago Up 7 hours app

```

**단계 5:**  
리버스 프록시 구성에 맞게 app.yml 파일을 업데이트합니다.

선호하는 텍스트 편집기를 사용하여 `/var/discourse/container/app.yml`을 엽니다.  
다음 줄을 대체/주석 처리합니다: (이는 로컬 Nginx에서 처리합니다)

```plaintext
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"

```

`#- "templates/web.letsencrypt.ssl.template.yml"` 바로 다음에 다음을 추가합니다:

```plaintext
- "templates/web.socketed.template.yml"

```

그런 다음 discourse가 이제 웹소켓을 사용하므로 expose 섹션을 주석 처리합니다. 마지막으로 nginx는 필요한 80 및 443 포트를 로컬에서 해제할 수 있으므로 시작할 수 있습니다.

```plaintext
#expose:
# - "80:80" # http
# - "443:443" # https

```

이제 Discourse가 HTTPS로만 링크를 제공하도록 강제하려면 `env` 섹션에 다음을 추가하십시오:

```plaintext
# FORCE SSL 
DISCOURSE_FORCE_HTTPS: true

```

이제 마침으로 작업을 시작하려면 앱을 다시 빌드해야 합니다. 다음을 사용합니다:

```plaintext
cd /var/discourse
./launcher rebuild app

```

실행을 완료되도록 둡니다. 성공했는지 확인하려면 docker run 명령이 표시되는지 확인하거나 단순히 `docker ps`를 실행하면 컨테이너가 실행 중임을 볼 수 있습니다.

**단계 6:**

Nginx를 활성화하고 기본 사이트를 docker 컨테이너를 가리키도록 구성합니다. 로컬 nginx를 사용하여 리버스 프록시가 컨테이너에 액세스할 수 있도록 합니다.

다음과 같이 실행합니다:

```plaintext
systemctl enable nginx && systemctl start nginx

```

실행 중인지 확인하려면 브라우저와 로컬 IP를 사용하여 nginx의 기본 랜딩 페이지에 액세스해 보십시오.  
예:

```plaintext
http://10.10.0.4

```

Nginx의 축하 페이지가 표시되어야 합니다.

**단계 7:**  
기본 구성을 다음으로 업데이트합니다.  
먼저 구성 파일을 비웁니다:

```plaintext
echo "" > /etc/nginx/sites-available/default

```

텍스트 편집기를 사용하여 구성 파일을 열고 다음을 추가합니다:  
**참고:** `server_name`을 도메인으로, `ssl_certificate`, `ssl_certificate_key`을 SSL 인증서와 키 파일 위치로 업데이트하십시오.  
Certbot을 사용할 수 있지만 저는 단순히 리버스 프록시에서 인증서와 키를 `rsync`합니다.

```plaintext
server {
    listen 80; listen [::]:80;
    server_name add.yourdomain.com;
    server_tokens off;
    return 301 https://$host$request_uri;
}
# Default server configuration
#
server {
	# SSL configuration
	#
	server_tokens off;
	listen 443 ssl default_server;
	listen [::]:443 ssl default_server;

    server_name add.yourdomain.com;
	ssl_certificate /etc/ssl/certs/your_ssl_cert.bundle;
	ssl_certificate_key /etc/ssl/private/your_ssl_cert.key;
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
	ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
	ssl_prefer_server_ciphers on;
	location / {
		proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock;
		proxy_set_header Host $http_host;
		proxy_http_version 1.1;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;
		proxy_set_header X-Real-IP $remote_addr;
	}
}

```

새 기본 파일을 저장하고 `systemctl restart nginx`를 실행합니다.

**단계 8:**

브라우저를 열고 포럼 도메인 [https://somedomain.com으로](https://somedomain.xn--com-ky7m580d) 이동하면 다음 페이지가 표시됩니다.

[![](https://global.discourse-cdn.com/meta/original/4X/4/3/b/43b2cbd8bd8c1122a4377c985ee7dbb1d43bdbec.png) ](https://global.discourse-cdn.com/meta/original/4X/4/3/b/43b2cbd8bd8c1122a4377c985ee7dbb1d43bdbec.png)

이상으로 모든 것이 끝났습니다. 이제 등록 단계를 따르고 포럼/커뮤니티를 시작할 수 있습니다 :).

**추가 단계:**

> **설치 후 유지 관리**  
> OS의 자동 보안 업데이트를 켜는 것을 강력히 권장합니다. Ubuntu에서는 dpkg-reconfigure -plow unattended-upgrades를 사용합니다.

지원이 필요하면 이 커뮤니티를 사용하면 되며, 로컬 Nginx에 대해서는 이 게시물에서 도움을 요청할 수 있습니다.

---

<div class="post-metadata">

### Author: ![Anil\_S](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/anil_s/32/373408_2.png) [@Anil\_S](https://meta.discourse.org/u/Anil_S)
#### Post date: [3월 24, 2024, 3:53오후 UTC](https://meta.discourse.org/t/installing-discourse-behind-reverse-proxy-using-recommended-supported-installation/300191/2 "2024-03-24T15:53:25Z")

</div>

정말 좋습니다. 감사합니다.

이 가이드에서 개선되었으면 하는 한 가지가 있습니다. 바로 nginx를 통해 정적 에셋을 서빙할 수 있도록 하는 것입니다.

현재 위 구성에서는 모든 정적 요청이 워커로 전달되고 있습니다. 이 문제를 우회하는 방법을 아직 알아보는 중이며, 방법을 찾게 되면 업데이트를 게시하겠습니다.

---

<div class="post-metadata">

### Author: ![NullUsername](https://avatars.discourse-cdn.com/v4/letter/n/a183cd/32.png) [@NullUsername](https://meta.discourse.org/u/NullUsername)
#### Post date: [3월 27, 2024, 11:58오전 UTC](https://meta.discourse.org/t/installing-discourse-behind-reverse-proxy-using-recommended-supported-installation/300191/3 "2024-03-27T11:58:48Z")

</div>

> [@Anil\_S](#):
>
> 이 가이드에 개선 사항으로 보고 싶은 것 중 하나는 nginx를 통해 정적 자산(static assets)을 서빙하는 기능입니다.

정적 파일에 대해 좀 더 구체적으로 설명해 주실 수 있나요?

혹시 nginx의 404, 302, 500 정적 페이지를 말씀하시는 건가요, 아니면 Discourse의 정적 페이지를 말씀하시는 건가요?

조금 조사해 본 결과, 404 페이지의 리다이렉트는 작동하는 것을 확인했습니다. 다만 500 에러 페이지를 설정하는 것만은 아직 방법을 찾지 못했습니다.

제가 정확히 무엇을 찾아봐야 하는지 알 수 있도록 좀 더 구체적으로 말씀해 주시겠습니까? 🙂

---

<div class="post-metadata">

### Author: ![jhary](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jhary/32/480899_2.png) [@jhary](https://meta.discourse.org/u/jhary)
#### Post date: [1월 14, 2025, 10:01오후 UTC](https://meta.discourse.org/t/installing-discourse-behind-reverse-proxy-using-recommended-supported-installation/300191/4 "2025-01-14T22:01:31Z")

</div>

이 가이드는 훌륭합니다. 웹사이트를 로드하는 단계까지 전체 과정을 따라갔습니다. 그런데 “too many redirects”(리다이렉트 횟수 초과) 오류가 발생합니다. IP 주소를 사용하면 Discourse는 정상적으로 로드되지만, 리다이렉트 문제를 해결하지 못하고 있습니다. 정말 아깝네요.

도움 주시면 감사하겠습니다.

감사합니다.

---

<div class="post-metadata">

### Author: ![sandra.mccollum](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sandra.mccollum/32/441742_2.png) [@sandra.mccollum](https://meta.discourse.org/u/sandra.mccollum)
#### Post date: [2월 10, 2025, 1:31오후 UTC](https://meta.discourse.org/t/installing-discourse-behind-reverse-proxy-using-recommended-supported-installation/300191/5 "2025-02-10T13:31:01Z")

</div>

이 문제를 해결하는 방법을 아시는 분 계신가요? 사이트는 정상적으로 작동하지만, 컨테이너의 nginx error.log에서 이러한 오류를 발견했습니다. 위 지침에 따라 리버스 프록시를 설정하여 사용하고 있습니다.

컨테이너의 /etc/nginx/conf.d/discourse.conf 파일을 확인해 보니 다음과 같이 되어 있습니다.

```plaintext
upstream discourse { server 127.0.0.1:3000; }

이것이 다음과 같은 형태여야 하나요?:

upstream discourse { http://unix:/var/discourse/shared/standalone/nginx.http.sock; }

```

컨테이너의 /var/log/nginx를 확인해 보면 다음과 같은 오류가 표시됩니다:

```plaintext
2025/02/09 21:00:21 [error] 69#69: *1 connect() failed (111: Connection refused) while connecting to upstream, client: xx.xx.xxx.xxx, server: _, request: "POST /message-bus/b39980c2387e4750bc1e320cb6195424/poll?dlp=t HTTP/1.1", upstream: "http://127.0.0.1:3000/message-bus/b39980c2387e4750bc1e320cb6195424/poll?dlp=t", host: "discourse.xxxx.com"

2025/02/09 21:00:23 [error] 67#67: *3 connect() failed (111: Connection refused) while connecting to upstream, client: xx.xx.xx.xxx, server: _, request: "GET /chat/api/me/channels HTTP/1.1", upstream: "http://127.0.0.1:3000/chat/api/me/channels", host: "discourse.xxxx.com"

2025/02/09 21:00:23 [error] 70#70: *5 connect() failed (111: Connection refused) while connecting to upstream, client: xx.xx.xx.xxx, server: _, request: "POST /message-bus/d95b6999d26242f28f4875732b195440/poll HTTP/1.1", upstream: "http://127.0.0.1:3000/message-bus/d95b6999d26242f28f4875732b195440/poll", host: "discourse.xxxx.com"

```

감사합니다!

---

<div class="post-metadata">

### Author: ![Arkshine](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/arkshine/32/298682_2.png) [@Arkshine](https://meta.discourse.org/u/Arkshine)
#### Post date: [2월 10, 2025, 1:46오후 UTC](https://meta.discourse.org/t/installing-discourse-behind-reverse-proxy-using-recommended-supported-installation/300191/6 "2025-02-10T13:46:31Z")

</div>

> [@sandra.mccollum](#):
>
> 위 설명에 따라 리버스 프록시를 설정하여 사용하고 있습니다.

5단계를 제대로 따르셨나요? 소켓을 사용하지 않는 것 같습니다.

> [@NullUsername](#):
>
> `proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock;`

---

<div class="post-metadata">

### Author: ![sandra.mccollum](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sandra.mccollum/32/441742_2.png) [@sandra.mccollum](https://meta.discourse.org/u/sandra.mccollum)
#### Post date: [2월 10, 2025, 2:03오후 UTC](https://meta.discourse.org/t/installing-discourse-behind-reverse-proxy-using-recommended-supported-installation/300191/7 "2025-02-10T14:03:56Z")

</div>

네, 컨테이너 외부의 로컬 리버스 프록시에서 소켓을 사용하고 있으며, app.yml의 5단계를 따랐습니다.

```plaintext
/var/discourse/containers# grep web.socketed.template.yml app.yml
  - "templates/web.socketed.template.yml"

/var/discourse/containers# grep templates/web.ssl.template.yml app.yml
  # - "templates/web.ssl.template.yml"

/var/discourse/containers# grep templates/web.letsencrypt.ssl.template.yml app.yml
  # - "templates/web.letsencrypt.ssl.template.yml"

/var/discourse/containers# grep http app.yml

# - "80:80" # http
# - "443:443" # https

/var/discourse/containers# grep DISCOURSE_FORCE_HTTPS app.yml
DISCOURSE_FORCE_HTTPS: true

```

```plaintext
templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  ## IPv6 리스너를 활성화하려면 다음 줄의 주석을 해제하세요
  #- "templates/web.ipv6.template.yml"
  - "templates/web.ratelimited.template.yml"
  ## Lets Encrypt(https)를 추가하려면 다음 두 줄의 주석을 해제하세요
  # - "templates/web.ssl.template.yml"
  # - "templates/web.letsencrypt.ssl.template.yml"
  - "templates/web.socketed.template.yml"
## 이 컨테이너에서 노출할 TCP/IP 포트는?
## Apache나 nginx와 같은 다른 웹서버와 포트를 공유하려면
## 자세한 내용은 https://meta.discourse.org/t/17247 을 참조하세요
#expose:
# - "80:80" # http
# - "443:443" # https

```

이것을 확인했습니다: [Discourse working with jwilder /nginx proxy & acme-companion](https://meta.discourse.org/t/discourse-working-with-jwilder-nginx-proxy-acme-companion/217059)

하지만 제 문제와 관련하여 이 내용을 이해하기가 어렵습니다…

---

<div class="post-metadata">

### Author: ![dogojosho](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/dogojosho/32/553655_2.png) [@dogojosho](https://meta.discourse.org/u/dogojosho)
#### Post date: [5월 6, 2026, 9:32오후 UTC](https://meta.discourse.org/t/installing-discourse-behind-reverse-proxy-using-recommended-supported-installation/300191/9 "2026-05-06T21:32:12Z")

</div>

여기요, 이 글을 발견하시는 분들을 위해 2026년 5월 업데이트 정보를 공유합니다:

저는 NPM Plus를 사용 중입니다. 여기 있는 지침을 따랐지만, 다른 분들 중 NPM Plus를 사용 중인 분들을 위해 추가 설명을 드리고자 합니다:  
여기에 나열된 수동 Nginx 설정, 또는 커스텀 로케이션, 또는 고급 설정을 사용할 필요 없이, 제공된 Unix URL의 끝부분 세미콜론을 **제거** 하고 포트란을 비워 두면 됩니다. 또한 커스텀 로케이션과 고급 설정도 완전히 비워 두시기 바랍니다.

예시를 위한 이미지는 아래를 참조하세요.

 ![image](https://global.discourse-cdn.com/meta/original/4X/1/8/1/181934014863492dc9adcea6ad6ab0e15c1e2021.png)

정규 NPM에서는 이 방법을 시도해 보지 않았지만, 일반/표준 NPM에서도 작동할 수 있고 작동하지 않을 수도 있습니다.

감사합니다!
