Docker에 Discourse 설치 후 연결되지 않음

그래서 표준 설치 문서를 참고해서 진행했는데, 모든 과정이 정상적으로 완료된 것 같았습니다. 그 후 app.yml 파일을 편집하여 사용할 포트 변경을 하고, LetsEncrypt 주석을 처리한 뒤 재구축을 했습니다. 이것도 모두 정상적으로 끝난 것으로 보입니다.

하지만 가장 직접적인 방법으로 접속을 시도해 보면:

$lynx https://127.0.0.1:44443

다음과 같은 오류가 발생합니다:

경고!: 원격 호스트와 안전한 연결을 설정할 수 없습니다.

포트에 ping조차 보내지 못합니다.

이것이 어떤 의미인지 이해가 가지 않습니다. 컨테이너 내부에 로그가 있나요?

—추가 편집----

$ sudo ./launcher logs app
run-parts: executing /etc/runit/1.d/00-ensure-links
run-parts: executing /etc/runit/1.d/00-fix-var-logs
run-parts: executing /etc/runit/1.d/01-cleanup-web-pids
run-parts: executing /etc/runit/1.d/anacron
run-parts: executing /etc/runit/1.d/cleanup-pids
Cleaning stale PID files
run-parts: executing /etc/runit/1.d/copy-env
Started runsvdir, PID is 43
ok: run: redis: (pid 56) 0s
**chgrp: invalid group: ‘syslog’**
ok: run: postgres: (pid 55) 0s
supervisor pid: 57 unicorn pid: 85
(57) Reopening logs

----추가 편집----

root@hestia-app:/shared/log/rails# tail -f *.log
==> production_errors.log <==

==> production.log <==

==> sidekiq.log <==

==> unicorn.stderr.log <==
I, [2021-08-06T00:56:35.859967 #85]  INFO -- : master done reopening logs
I, [2021-08-06T00:56:50.911700 #142]  INFO -- : worker=0 done reopening logs
I, [2021-08-06T00:56:50.911698 #152]  INFO -- : worker=1 done reopening logs
I, [2021-08-06T00:56:50.935834 #162]  INFO -- : worker=2 done reopening logs
I, [2021-08-06T00:56:50.941733 #233]  INFO -- : worker=7 done reopening logs
I, [2021-08-06T00:56:50.945447 #203]  INFO -- : worker=5 done reopening logs
I, [2021-08-06T00:56:50.947354 #172]  INFO -- : worker=3 done reopening logs
I, [2021-08-06T00:56:50.949949 #187]  INFO -- : worker=4 done reopening logs
I, [2021-08-06T00:56:50.953453 #213]  INFO -- : worker=6 done reopening logs

==> unicorn.stdout.log <==
Sidekiq PID 131 done reopening logs...
root@hestia-app:/var/log/nginx# tail *.log
==> access.letsencrypt.log <==

==> access.log <==

==> error.letsencrypt.log <==

==> error.log <==

도커 오류일 것 같은데… 다른 건 다 정상으로 보이니까.

8088 포트에 매핑된 순수한 아파치 컨테이너를 설치했는데, lynx에서 잘 작동합니다.

다시 앱에 접속하여 ps ax 명령을 실행해 보니 모든 것이 정상적으로 작동하는 것 같습니다. 컨테이너가 연결을 받지 못하고 있는 것 같습니다.

root@hestia-app:/var/www/discourse# ps ax
    PID TTY      STAT   TIME COMMAND
      1 pts/0    Ss+    0:00 /bin/bash /sbin/boot
     43 pts/0    S+     0:00 /usr/bin/runsvdir -P /etc/service
     44 ?        Ss     0:00 runsv cron
     45 ?        Ss     0:00 runsv rsyslog
     46 ?        Ss     0:00 runsv redis
     47 ?        Ss     0:00 runsv postgres
     48 ?        Ss     0:00 runsv unicorn
     49 ?        Ss     0:00 runsv nginx
     50 ?        S      0:00 cron -f
     51 ?        Sl     0:00 rsyslogd -n
     52 ?        S      0:00 nginx: master process /usr/sbin/nginx
     53 ?        S      0:00 svlogd /var/log/redis
     54 ?        S      0:00 svlogd /var/log/postgres
     55 ?        S      0:00 /usr/lib/postgresql/13/bin/postmaster -D /etc/postgresql/13/main
     56 ?        Sl     0:33 /usr/bin/redis-server *:6379
     57 ?        S      0:04 /bin/bash config/unicorn_launcher -E production -c config/unicorn.conf.rb
     64 ?        S      0:00 nginx: worker process
     65 ?        S      0:00 nginx: worker process
     66 ?        S      0:00 nginx: worker process
     67 ?        S      0:00 nginx: worker process
     68 ?        S      0:00 nginx: cache manager process
     79 ?        Ss     0:00 postgres: 13/main: checkpointer 
     80 ?        Ss     0:00 postgres: 13/main: background writer 
     81 ?        Ss     0:03 postgres: 13/main: walwriter 
     82 ?        Ss     0:00 postgres: 13/main: autovacuum launcher 
     83 ?        Ss     0:00 postgres: 13/main: stats collector 
     84 ?        Ss     0:00 postgres: 13/main: logical replication launcher 
     85 ?        Sl     0:13 unicorn master -E production -c config/unicorn.conf.rb
    113 ?        Ss     0:01 postgres: 13/main: discourse discourse [local] idle
    131 ?        SNl    0:48 sidekiq 6.2.1 discourse [0 of 5 busy]
    142 ?        Sl     0:06 unicorn worker[0] -E production -c config/unicorn.conf.rb
    152 ?        Sl     0:06 unicorn worker[1] -E production -c config/unicorn.conf.rb
    162 ?        Sl     0:07 unicorn worker[2] -E production -c config/unicorn.conf.rb
    172 ?        Sl     0:06 unicorn worker[3] -E production -c config/unicorn.conf.rb
    180 ?        Ss     0:00 postgres: 13/main: discourse discourse [local] idle
    187 ?        Sl     0:07 unicorn worker[4] -E production -c config/unicorn.conf.rb
    203 ?        Sl     0:07 unicorn worker[5] -E production -c config/unicorn.conf.rb
    213 ?        Sl     0:07 unicorn worker[6] -E production -c config/unicorn.conf.rb
    233 ?        Sl     0:07 unicorn worker[7] -E production -c config/unicorn.conf.rb
  11733 pts/1    Ss     0:00 /bin/bash --login
  11748 ?        S      0:00 sleep 1
  11749 pts/1    R+     0:00 ps ax

좋아요, 그래서 앱을 입력하고 discord 도커 안에 lynx를 설치했는데, 거기서 잘 환영 페이지를 볼 수 있습니다! 즉, 설치는 정상적으로 작동하며, 도커 내부에서 서버 외부로의 네트워크 매핑이 문제입니다.

다음은 docker ps 출력 결과입니다:

CONTAINER ID   IMAGE                 COMMAND        CREATED          STATUS          PORTS                                             NAMES
c6d0209e4e72   local_discourse/app   "/sbin/boot"   51 minutes ago   Up 51 minutes   127.0.0.1:8880->80/tcp, 127.0.0.1:4443->443/tcp   app

…그리고 여기는 app.yml 정보입니다:

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"

expose:
  - "127.0.0.1:8880:80"   # http
  - "127.0.0.1:4443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"
  db_shared_buffers: "2048MB"

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

  UNICORN_WORKERS: 8

  DISCOURSE_HOSTNAME: [redacted]


  DISCOURSE_SMTP_ADDRESS: [redacted]
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: [redacted]
  DISCOURSE_SMTP_PASSWORD: "[redacted]"
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (선택 사항, 기본값 true)
  DISCOURSE_SMTP_DOMAIN: [redacted]
  DISCOURSE_NOTIFICATION_EMAIL: [redacted]


## Docker 컨테이너는 상태가 없으며(stateless), 모든 데이터는 /shared에 저장됩니다
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## 플러그인은 여기에 설치합니다
## 자세한 내용은 https://meta.discourse.org/t/19157 참조
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git

## 빌드 후 실행할 사용자 지정 명령
run:
  - exec: echo "Beginning of custom commands"
  - exec: echo "End of custom commands"

아, 이제 원인을 알겠다. 8880:80은 정상적으로 작동했고, 나는 4443:443 쪽만 테스트하고 있었다. 인증서 오류로 인해 해당 쪽은 작동하지 않았다. 가상 호스트 레벨의 웹서버에서 인증서를 설치하고 관리할 계획이다. 모든 설정이 정상적으로 작동하는 대로 관심 있는 분들을 위해 최종 해결책을 공유하겠다.

설치 환경
Hestia Control Panel (서버 관리용)
Apache2 (웹 서버)
Docker에서 실행 중인 Discourse를 Apache2로 리버스 프록시 설정
Let’sEncrypt는 리버스 프록시되지 않으며, www_root에서 Hestia가 관리

  1. app.yml에서 unix 소켓을 설정하고 (재빌드):n```
  • “templates/web.socketed.template.yml”
2) app.yml에서 포트 매핑과 Let'sEncrypt를 제거하고 (재빌드)

- “templates/web.ssl.template.yml”

- “templates/web.letsencrypt.ssl.template.yml”

- “80:80” # http

- “443:443” # https

LETSENCRYPT_ACCOUNT_EMAIL: {your email, probably}


3) HestiaCP를 위한 대안적인 apache2.conf 템플릿을 다음과 같이 생성합니다 (hestiacp를 사용하지 않는 분들을 위해, %{replace 태그}%는 다른 apache2.conf 파일을 보면 꽤 표준적이고 명확한 것임을 알 수 있습니다. 가장 중요한 부분들은 %{replace 태그}%를 많이 사용하지 않습니다. 또한 설정에 따라 *standalone* 텍스트가 *socket-only*일 수 있습니다. 기억나지 않으면 /var/discourse/shared/ 디렉터리에 무엇이 있는지 확인해 보세요.

{Custom Template}.stpl

<VirtualHost %ip%:%web_ssl_port%>

ServerName %domain_idn%

ProxyPreserveHost On
ProxyRequests Off
ProxyPass / unix:/var/discourse/shared/standalone/nginx.http.sock|http://localhost/
ProxyPassReverse  / unix:/var/discourse/shared/standalone/nginx.http.sock|http://localhost/

ServerAdmin %email%

Alias /vstats/ %home%/%user%/web/%domain%/stats/
Alias /error/ %home%/%user%/web/%domain%/document_errors/

CustomLog /var/log/%web_system%/domains/%domain%.bytes bytes
CustomLog /var/log/%web_system%/domains/%domain%.log combined
ErrorLog /var/log/%web_system%/domains/%domain%.error.log
<Directory %home%/%user%/web/%domain%/stats>
    AllowOverride All
</Directory>
<Directory %sdocroot%>
    AllowOverride All
    SSLRequireSSL
    Options +Includes -Indexes +ExecCGI
</Directory>
SSLEngine on
SSLVerifyClient none
SSLCertificateFile %ssl_crt%
SSLCertificateKeyFile %ssl_key%
%ssl_ca_str%SSLCertificateChainFile %ssl_ca%

IncludeOptional %home%/%user%/conf/web/%domain%/%web_system%.ssl.conf_*

{Custom Template}.tpl

<VirtualHost %ip%:%web_port%>

ServerName %domain_idn%
%alias_string%

ProxyPreserveHost On
ProxyRequests Off
ProxyPass / unix:/var/discourse/shared/standalone/nginx.http.sock|http://localhost/
ProxyPassReverse  / unix:/var/discourse/shared/standalone/nginx.http.sock|http://localhost/

RewriteEngine On
RewriteCond %{REQUEST_URI} !^.well-known/acme-challenge
RewriteRule ^(.*) https://%domain_idn%/$1 [R=301,L]

Alias /vstats/ %home%/%user%/web/%domain%/stats/
Alias /error/ %home%/%user%/web/%domain%/document_errors/

CustomLog /var/log/%web_system%/domains/%domain%.bytes bytes
CustomLog /var/log/%web_system%/domains/%domain%.log combined
ErrorLog /var/log/%web_system%/domains/%domain%.error.log

<Directory %home%/%user%/web/%domain%/stats>
    AllowOverride All
</Directory>
<Directory %sdocroot%>
    AllowOverride All
    Options +Includes -Indexes +ExecCGI
</Directory>

IncludeOptional %home%/%user%/conf/web/%domain%/%web_system%.conf_*
```

아, 위에서 뭔가 놓쳤네요. 각 파일에 이것도 필요합니다:

RequestHeader set X-Forwarded-Proto https