Discourse 설정 - AWS Linux 2 AMI 및 Apache2(httpd) 환경

안녕하세요 모두

문서와 게시된 설정 및 권장 사항을 모두 확인하고, 제 상황에 맞게 수정해 보려 시도했습니다.

매우 단순해 보이는 작업인데, 제안된 어떤 솔루션도 작동하지 않아 incredibly frustrate합니다.

저희 환경:

  • AWS EC2 인스턴스를 사용 중이며, 구체적으로는 AWS Linux 2 AMI입니다;
  • apache2가 실행 및 설정되어 있습니다;
  • 해당 인스턴스는 AWS 로드 밸런서에 의해 참조되는 AWS 타깃 그룹의 일부입니다;
  • SSL/TLS 인증서는 AWS에서 제공하며 로드 밸런서에 연결되어 있습니다;
  • 도메인 제공자는 name.com입니다;
  • 설정의 일환으로 CNAME 레코드를 사용하여 여러 서브도메인을 AWS 로드 밸런서로 라우팅하며, 로드 밸런서가 EC2 인스턴스로의 트래픽을 관리합니다;
  • 로드 밸런서로 라우팅되고 웹 사용자에게 제공되는 모든 트래픽은 보안(HTTPS)입니다;
  • 서버에서 세 개의 독립적인 node express 애플리케이션을 실행하고 있습니다;
  • 포트는 express 서버 설정의 일부로 express에서 정의되며, 현재 3000, 4000, 5000 포트입니다;
  • 트래픽은 서브도메인을 기준으로 apache가 관련 웹 앱으로 라우팅합니다. 예를 들어:
<VirtualHost *:80>
    ServerName subdomain.domain.io
    ProxyPreserveHost On
    ProxyPass "/" "http://localhost:4000/"
    ProxyPassReverse "/" "http://localhost:4000/"
</VirtualHost>
  • 특별히 관련은 없지만, 서버 재시작 시 자동으로 시작되도록 PM2를 사용하여 express 앱을 관리합니다.

  • 동일한 서버에 docker가 설치되어 있습니다;

  • app.yaml 복사본을 사용하여 discourse도 설치했습니다(Run other websites on the same machine as Discourse - #182 by angus 를 참고함).

현재 상태:

  • Docker는 실행 중입니다
  • Discourse 앱(컨테이너)은 실행 중입니다
  • Express 앱들은 모두 실행 중이며 apache에 의해 올바르게 라우팅되고 있습니다

메모:

  • 처음에는 문서대로 포트를 노출하지 않고 앱을 빌드해 보았으나, 작동하지 않아 HTTP 포트 80으로 포트 8000을 노출했습니다;
  • 제 단순한 이해에 따르면 docker는 집과 같고, 다양한 컨테이너는 방과 같습니다. Docker는 앱이 어떻게 접근되는지(즉, 어떤 방을 접근할지)를 결정합니다. 포트 8000을 노출하면 이제 8000이 노출되었으므로 다른 express 앱처럼 포트 8000을 참조할 수 있을 것이라 생각했습니다. 하지만 이는 작동하지 않으며, apache에서 시도한 것의 예시는 다음과 같습니다:
# FAQ (DISCOURSE ROUTES)

<VirtualHost *:80>
    ServerName discourse.domain.io
    ProxyPreserveHost On
    ProxyPass "/" "http://localhost:8000/"
    ProxyPassReverse "/" "http://localhost:8000/"
</VirtualHost>
  • 단순한 테스트는 서버에서 브라우저에 localhost:8000을 입력해 보는 것이었습니다. 서버는 chromium이 설치된 AWS 가이드입니다. 이것이 즉시 해결되지 않는다는 사실은 문제가 있으며 제 이해에 근본적인 무언가가 빠져 있음을 알려줍니다. 제 웹 앱은 express 설정에서 지정하는 포트에서 실행되고 사용 가능하며, docker 컨테이너도 동일할 것으로 기대했습니다.

추가 메모:

  • NGINX를 apache와 docker 앞에 배치하여 discourse.domain.io 트래픽을 로컬 서버의 포트 8000(즉, docker 컨테이너를 위해 노출된 포트)으로 라우팅하고, *.domain.io의 모든 다른 트래픽을 예를 들어 포트 9000의 apache로 라우팅한 후, 포트 9000에서 트래픽을 라우팅하도록 가상 호스트 구성을 변경하는 것이 잠재적인 해결책임을 인지하고 있습니다. 즉, 다음과 같이:
# EXPRESS APP ROUTING IN APACHE

<VirtualHost *:9000>
    ServerName other_sub_domains.domain.io
    ProxyPreserveHost On
    ProxyPass "/" "http://localhost:4000/"
    ProxyPassReverse "/" "http://localhost:4000/"
</VirtualHost>
  • 제게 이것은 완전히 불필요해 보입니다. 도메인 discourse.domain.io가 apache로 라우팅되고 apache가 요청을 받은 후 라우팅을 시도한다면, docker 컨테이너의 노출된 포트로 가리키는 것만큼 간단해야 합니다.
  • 또한 서버 자체에서 localhost:8000이 해결되지 않는다면, 이 방식은 어차피 작동하지 않을 것입니다.

현재 discourse docker 컨테이너로 이동하려고 할 때 chrome에서 502 오류가 발생합니다. (위 스크린샷 참조).

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"
  - "templates/web.socketed.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:
  - "8000:80"   # http
  #- "443:443" # https

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: "256MB"

  ## 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:
  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

  ## TODO: The domain name this Discourse instance will respond to
  ## Required. Discourse will not work with a bare IP number.
  DISCOURSE_HOSTNAME: 'discourse.domain.io'

  ## 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: 'user@domain.io'

  ## 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: email-smtp.us-east-1.amazonaws.com
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: ******
  DISCOURSE_SMTP_PASSWORD: ******
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (optional, default true)
  #DISCOURSE_SMTP_DOMAIN: ******    # (required by some providers)
  #DISCOURSE_NOTIFICATION_EMAIL: ******  # (address to send notifications from)

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

  ## 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 maxmind geolocation IP address key for IP address lookup
  ## see https://meta.discourse.org/t/-/137387/23 for details
  #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456

## 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"

제 도메인, 이메일 주소 및 이메일 구성은 정확합니다. 언급했듯이, SSL/TLS 구성은 필요하지 않습니다.

요청 사항:

  • 이 설정을 작동시키는 유일한 방법이 NGINX 솔루션인 것이며, 그렇다면 설정 단계에 대해 더 명확한 설명이 가능한가요? discourse를 작동시키기 위해 서버를 처음부터 다시 시작할 위치에 있지 않으며, 보장도 없습니다.
  • Discourse behind reverse proxy and https - #2 by itsbhanusharma 에서 @Dark Matter 님은 다음을 apache2 솔루션으로 제공했지만, 이 솔루션이 node express 환경을 고려한 것이라 생각하지 않으며, 제 localhost:8000이 해결되지 않으므로 이것이 작동할지 확실하지 않습니다:
<VirtualHost *:80>
  ServerAdmin webmaster@localhost
  ServerName  discourse.example.com
  DocumentRoot /website/discourse

  RewriteEngine On
  ProxyPreserveHost On
  ProxyRequests Off
  ProxyPass / unix:/var/discourse/shared/socket-only/nginx.http.sock|http://localhost/
  ProxyPassReverse  / unix:/var/discourse/shared/socket-only/nginx.http.sock|http://localhost/
  ErrorLog /var/log/apache2/discourse.error.log
  LogLevel warn
  CustomLog /var/log/apache2/discourse.access.log combined

  RewriteCond %{SERVER_NAME} =discourse.example.com
  RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
  • 문제는 제 discourse 구성에 있는 것인가요? 아마도 제 apache 라우팅 문제일까요(의심 중)? 아니면 여기서 더 근본적인 무언가를 놓치고 있는 것인가요?
  • 이것이 해결되면 향후 많은 사용자에게 도움이 될 것이라고 생각합니다.
  • 1등 상은 서버 내에서 discourse로 로컬 라우팅을 하는 것입니다.
  • 그 다음 상은 URL을 통한 라우팅입니다.

감사합니다
Matthew Lucas

이것은 제가 완전히 이해하기엔 너무 복잡해서, 해결책이라기보다는 단순한 추측 정도로 봐주세요. 만약 실행 중인 도커 컨테이너에 로컬호스트를 통해 무언가를 연결하지 못하는 것이 문제라면, 도커 IP를 사용해 볼 수 있습니다. 웹소켓 템플릿을 사용하여 포트 대신 소켓을 사용하는 것도 가능할 수 있습니다. 일부에서는 여러 이유로 이것이 더 바람직하다고 주장합니다.

MKJ’s Opinionated Discourse Deployment Configuration을 읽어보시는 것도 도움이 될 수 있습니다.

@pfaffman — @Matthew_Lucas는 이미 소켓 기반 템플릿을 사용 중이지만요…

저는 외부 프록시에 localhost를 사용하고 있으며, 이는 expose 설정과 함께 작동해야 합니다. 도커 IP를 사용해야 한다고 생각하지 않습니다. 또한 그 이유 때문에 Apache가 도커 컨테이너 앞에 있는 경우에만 실패할 것이라고도 생각하지 않습니다.

헤더 구성이 필요할 수 있습니다 — Add an offline page to display when Discourse is rebuilding or starting up - #2 by codinghorror 를 참조하세요.

Apache 구성을 잊으려 노력하고 있지만, 이 nginx 구성 부분은 Apache로 재현하는 방법을 알아내야 할 것 같습니다.

    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 https;
    proxy_set_header X-Real-IP $remote_addr;

특히 Host 헤더가 없으면 제대로 작동하지 않는다고 생각합니다.

HTTPS를 사용하지 않으므로, tcpdump를 사용하여 패킷 트레이스를 캡처하고 정확히 무엇이 잘못되는지 살펴볼 수 있어야 합니다.

그러나 왜 굳이 Apache를 넣는 걸까요? 그저 불필요한 단계일 뿐입니다. 제가 이런 것을 시도한다면, Amazon 로드 밸런서를 EC2 인스턴스의 8000 포트에 직접 연결하도록 설정할 것입니다. 아마도 HTTPS를 ELB에서 종료하고 있을 것이라고 가정합니다. 로드 밸런서가 사용자가 명시하지 않아도 일반적인 헤더를 추가하는 방법을 알고 있을 것이라고 추측하지만, 그렇지 않다면 당연히 설정해 두세요. 방화벽을 통해 해당 포트에 접근할 수 있는지 확인하는 것도 중요합니다.

여기서 더 많은 가치를 기여할 수 있을지 의문이지만, 이 내용들이 구성에 도움이 되길 바랍니다. 행운을 빕니다.

AWS EC2 리눅스에서 기존 HTTPD 리버스 프록시를 사용하여 DOCKER 및 DISCOURSE 설치

여러분 안녕하세요

해결했습니다. 처음부터 다시 시작하여 깨끗한 docker와 discourse 설치를 진행했습니다. 제 과정은 아래와 같습니다:

전제 조건

• AWS EC2 리눅스 인스턴스가 이미 있습니다
• SSH를 사용하여 EC2 인스턴스에 접근할 수 있습니다
• 서버에 Apache 2가 이미 설정되어 실행 중입니다

SSH를 사용하여 EC2 인스턴스에 접근

  1. CMD / 터미널을 엽니다

  2. AWS EC2 인스턴스에 SSH로 접속합니다

EC2 인스턴스에 연결된 후의 화면 예시

시스템 업데이트 수행

  1. 콘솔 / 터미널에서 다음 명령어를 실행하여 시스템 업데이트를 수행합니다

$ sudo yum update

DOCKER 설치

  1. 콘솔 / 터미널에서 다음 명령어를 실행하여 AWS Docker 패키지를 검색합니다

$ sudo yum search docker

  1. 콘솔 / 터미널에서 다음 명령어를 실행하여 버전 정보를 가져옵니다

$ sudo yum info docker

  1. 콘솔 / 터미널에서 다음 명령어를 실행하여 docker를 설치합니다

$ sudo yum install docker

  1. 기본 ec2-user에 그룹 멤버십을 추가하여 sudo 명령어 없이 모든 docker 명령어를 실행할 수 있도록 하기 위해 콘솔 / 터미널에서 다음 명령어를 실행합니다
$ sudo usermod -a -G docker ec2-user
$ id ec2-user

# 로그아웃 없이 Linux 사용자의 docker 그룹 할당을 다시 로드

$ newgrp docker
  1. 콘솔 / 터미널에서 다음 명령어를 실행하여 docker-compose를 설치합니다
# 1. pip3 (python 설치 프로그램 패키지) 가져오기
$ sudo yum install python3-pip
 
# 2. 다음 중 하나 실행
$ sudo pip3 install docker-compose # 루트 접근 권한 사용
 
# 또는
 
$ pip3 install --user docker-compose # 보안상의 이유로 루트 접근 권한 없이

# 권한 확인
$ sudo chmod -v +x /usr/local/bin/docker-compose
  1. 부팅 시 docker 서비스가 자동으로 시작되도록 하려면 콘솔 / 터미널에서 다음 명령어를 실행합니다

$ sudo systemctl enable docker.service

  1. 콘솔 / 터미널에서 다음 명령어를 실행하여 docker 서비스를 시작합니다

$ sudo systemctl start docker.service

  1. 콘솔 / 터미널에서 다음 명령어를 실행하여 docker 서비스가 실행 중인지 확인합니다. 출력 결과는 다음과 유사합니다

알아두면 좋은 기본 docker 명령어 :

# Docker 버전
$ docker version

# Docker compose 버전
$ docker-compose version

# Docker 서비스 시작
$ sudo systemctl start docker.service

# Docker 서비스 중지
$ sudo systemctl stop docker.service

# Docker 서비스 재시작
$ sudo systemctl restart docker.service

# Docker 서비스 상태
$ sudo systemctl status docker.service

DISCOURSE 설치

  1. discourse 폴더 생성

$ sudo mkdir /var/discourse

  1. discourse docker 이미지를 새로 생성된 디렉토리로 클론합니다

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

  1. standalone.yml 파일을 containers 폴더로 복사합니다

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

  1. 새로운 discourse.yml 파일을 다음과 같이 편집합니다. (중요한 부분은 http를 위한 공개 포트와 smtp를 위한 이메일 상세 정보입니다. 파일 내에서 수정해야 하며 복사하여 붙여넣지 마세요)

편집 옵션:

1. nano를 사용하여 커맨드 라인 / 터미널에서 편집할 수 있습니다
2. AWS에서 MATE를 PLUMA와 함께 사용하는 경우 PLUMA를 사용하여 파일을 편집할 수 있습니다
3. WINSCP를 사용하여 머신에 SSH로 접속하고 Windows GUI를 통해 파일을 편집할 수 있습니다

## 이것은 올인원, 스탠드얼론 Discourse Docker 컨테이너 템플릿입니다
##
## 이 파일을 변경한 후에는 반드시 다시 빌드해야 합니다
## /var/discourse/launcher rebuild app
##
## 편집할 때 *매우* 주의하세요!
## YAML 파일은 공백 또는 정렬 오류에 대해 매우 민감합니다!
## 필요할 때 이 파일을 검증하려면 http://www.yamllint.com/을 방문하세요

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"

## 이 컨테이너는 어떤 TCP/IP 포트를 공개해야 합니까?
## Apache 또는 nginx와 같은 다른 웹서버와 포트를 공유하려면
## 자세한 내용은 https://meta.discourse.org/t/17247을 참조하세요
expose:
  - "8080:80"   # http (로컬 포트 8080, docker 포트 80에서 실행)
  #- "443:443" # https (이것이 주석 처리되어 있는지 확인하세요)

params:
  db_default_text_search_config: "pg_catalog.english"

  ## db_shared_buffers는 총 메모리의 최대 25%로 설정하세요.
  ## 감지된 RAM 기반으로 bootstrap이 자동으로 설정하거나, 오버라이드할 수 있습니다
  #db_shared_buffers: "256MB"

  ## 정렬 성능을 향상시킬 수 있지만, 연결당 메모리 사용량이 증가합니다
  #db_work_mem: "40MB"

  ## 이 컨테이너는 어떤 Git 리비전을 사용해야 합니까? (기본값: tests-passed)
  #version: tests-passed

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

  ## 얼마나 많은 동시 웹 요청을 지원합니까? 메모리와 CPU 코어에 따라 다릅니다.
  ## 감지된 CPU 기반으로 bootstrap이 자동으로 설정하거나, 오버라이드할 수 있습니다
  #UNICORN_WORKERS: 3

  ## TODO: 이 Discourse 인스턴스가 응답할 도메인 이름
  ## 필수. Discourse는 IP 번호만으로는 작동하지 않습니다.
  DISCOURSE_HOSTNAME: 'faq.mobiloan.io'

  ## 컨테이너가 위에서 지정된 것과 동일한
  ## 호스트 이름(-h 옵션)으로 시작되도록 하려면 주석을 해제하세요 (기본값 "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: 초기 가입 시 관리자 및 개발자로 지정될 쉼표로 구분된 이메일 목록
  ## 예시 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: ‘ 여기에 이메일 입력 ’

  ## TODO: 새 계정을 검증하고 알림을 보내는 데 사용되는 SMTP 메일 서버
  # SMTP 주소, 사용자 이름 및 비밀번호가 필요합니다
  # 경고: SMTP 비밀번호의 '#' 문자는 문제를 일으킬 수 있습니다!
  DISCOURSE_SMTP_ADDRESS: SMTP 입력
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: 사용자 이름 입력
  DISCOURSE_SMTP_PASSWORD: 비밀번호 입력
  DISCOURSE_SMTP_ENABLE_START_TLS: true           # (선택 사항, 기본값 true, Amazon SES 사용)

 

  #DISCOURSE_SMTP_DOMAIN: discourse.example.com    # (일부 제공업체에서 요구)
  #DISCOURSE_NOTIFICATION_EMAIL: noreply@discourse.example.com    # (알림을 보내는 주소)

  ## Lets Encrypt 템플릿을 추가했다면 무료 SSL 인증서를 얻으려면 아래 주석을 해제하세요
  #LETSENCRYPT_ACCOUNT_EMAIL: me@example.com

  ## 이 Discourse 인스턴스의 http 또는 https CDN 주소 (가져오기 구성)
  ## 자세한 내용은 https://meta.discourse.org/t/14857을 참조하세요
  #DISCOURSE_CDN_URL: https://discourse-cdn.example.com
  
  ## IP 주소 조회를 위한 maxmind 지리 위치 IP 주소 키
  ## 자세한 내용은 https://meta.discourse.org/t/-/137387/23을 참조하세요
  #DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456

## Docker 컨테이너는 상태가 없습니다. 모든 데이터는 /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"
  ## 첫 번째 가입 시 'From' 이메일 주소를 설정하려면 주석을 해제하고 변경하세요:
  ## 첫 번째 가입 이메일을 받은 후, 해당 줄을 다시 주석 처리하세요. 한 번만 실행하면 됩니다.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "End of custom commands"
  1. 파일을 편집하고 저장한 후, 터미널에서 다음 명령어를 사용하여 discourse 앱을 다시 빌드합니다

$ /var/discourse/launcher rebuild discourse

참고: yaml 파일 이름이 다른 경우 discourse 대신 해당 yaml 파일 이름으로 대체해야 합니다

다시 빌드하는 데 시간이 걸린다는 점을 참고하세요.

  1. 앱이 다시 빌드되면 앱은 포트 8080에서 실행되어야 합니다. 이를 확인하려면 터미널에서 다음 명령어를 실행합니다

$ sudo lsof -i -P -n | grep LISTEN

포트 출력 예시

docker가 포트 8080에서 리스닝하고, httpd (apache)가 포트 80에서 리스닝하는 것을 확인하세요.

트래픽 라우팅 측면에서 apache가 웹 요청을 수신하고, 적절한 경우 discourse 컨테이너의 포트 8080으로 라우팅됩니다.

라우팅이 수행되도록 하려면 apache conf 파일에서 가상 호스트를 구성해야 합니다.

APACHE 가상 호스트 구성

  1. apache conf 파일은 /etc/httpd/conf.d/00-virtualhosts.conf에 위치합니다. httpd / apache / apache2는 서로 다른 apache 버전입니다. httpd 서비스를 사용하지 않는 경우 파일 위치가 다를 수 있지만, 이 경우 가상 호스트 구성은 동일합니다.

편집 옵션:

1. nano를 사용하여 커맨드 라인 / 터미널에서 편집할 수 있습니다
2. AWS에서 MATE를 PLUMA와 함께 사용하는 경우 PLUMA를 사용하여 파일을 편집할 수 있습니다
3. WINSCP를 사용하여 머신에 SSH로 접속하고 Windows GUI를 통해 파일을 편집할 수 있습니다

다음 내용을 추가하여 /etc/httpd/conf.d/00-virtualhosts.conf 파일을 편집합니다:

# FAQ (DISCOURSE ROUTES)

<VirtualHost *:80>
  	ServerName  sub.domain.com
  	ProxyPreserveHost On
    ProxyPass "/" "http://localhost:8080/"
    ProxyPassReverse "/" "http://localhost:8080/"
</VirtualHost>
  1. 서브 도메인이 AWS 서버 / 로드 밸런서를 가리키도록 관련 CNAME DNS 레코드를 생성해야 합니다.

저희 설정은 도메인 제공업체가 모든 트래픽을 AWS 로드 밸런서로 라우팅하기 때문에 약간 복잡합니다.

로드 밸런서는 AWS가 제공하는 인증서를 통해 SSL/TLS를 처리합니다.

로드 밸런서는 또한 트래픽을 AWS 인스턴스로 라우팅합니다.

Apache는 AWS 인스턴스에 설치되어 트래픽을 다음으로 라우팅합니다:

  • Node express 애플리케이션
  • Docker / discourse 애플리케이션.

결론

이것은 하나의 솔루션일 뿐이지만, 저희의 기존 설정에서 작동한 방법입니다.

다음 분들께 큰 감사를 드립니다:

Discourse에 관한 그의 글을 작성한 @Kane York,
중간에서 필요한 discourse 파일을 다운로드하는 방법에 대한 그의 노트를 작성한 @Axel Fernandes,
그리고 AWS Linux 2에 Docker를 설치하는 cyberciti의 글을 작성한 nixCraft의 @Vivek Gite.