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

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.