Nginx Proxy Manager를 사용해 Discourse로 여러 사이트 관리하기

두 컨테이너가 동일한 Docker 네트워크에 있는지 확인해야 합니다. NPM이 작동하지 않는다면 아직 Discourse 설정 문제가 아닙니다.

1개의 좋아요

MariaDB Docker 네트워크를 실수로 잊어버렸어요. 그런데

network_mode: bridge

를 추가한 후에도 npm에서 discourse 데이터베이스에 연결할 때 여전히 npm 오류가 발생하고 있어요.

  environment:
      DB_MYSQL_HOST: "172.17.0.2" #data container - 활성화했을 때 오류( error     connect ECONNREFUSED 172.17.0.2:3306 )를 받음.
#      DB_MYSQL_HOST: "db" 기본 npm 데이터베이스 (discourse 외부).
      DB_MYSQL_PORT: 3306
      DB_MYSQL_USER: "npm"
      DB_MYSQL_PASSWORD: "h4xb0xr1z__0k"
      DB_MYSQL_NAME: "npm"

pm과 maria가 모두 실행되면; maria 로그는 정상인데 npm은

error connect ECONNREFUSED 172.17.0.2:3306

오류가 나요.

무엇이 빠져 있나요?

1개의 좋아요

제 docker-compose 파일

version: "3"
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    network_mode: bridge
    restart: unless-stopped
    ports:
    
      - '80:80' # 공개 HTTP 포트
      - '443:443' # 공개 HTTPS 포트
      - '81:81' # 관리자 웹 포트

    environment:
      DB_MYSQL_HOST: "172.17.0.2" # 데이터 컨테이너 - 활성화 시 오류 발생 ( connect ECONNREFUSED 172.17.0.2:3306 ).
#      DB_MYSQL_HOST: "db" 기본 npm 데이터베이스 (discourse 외부).
      DB_MYSQL_PORT: 3306
      DB_MYSQL_USER: "npm"
      DB_MYSQL_PASSWORD: "mypassword"
      DB_MYSQL_NAME: "npm"

    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
#    depends_on:
#      - db

  db:
    image: 'mariadb:latest'
    restart: unless-stopped
    network_mode: bridge
    environment:
      MYSQL_ROOT_PASSWORD: 'mypassword'
      MYSQL_DATABASE: 'npm'
      MYSQL_USER: 'npm'
      MYSQL_PASSWORD: 'mypassword'
    volumes:
      - ./data/mysql:/var/lib/mysql

data + web-only 구성으로 discourse를 실행 중입니다. npm과 maria 이후의 IP 매핑은 다음과 같습니다:

data 컨테이너 IP: 172.17.0.2
web_only 컨테이너 IP: 172.17.0.3
npm 컨테이너 IP: 172.17.0.5
maria data (npm) IP: 172.17.0.4
1개의 좋아요

Hi @tophee

MariaDB의 문제들보다 SQLite를 NPM과 함께 사용하는 것이 더 쉽고 신뢰할 수 있다고 생각하는데, 이에 대한 추천을 받을 수 있을까요?

저는 NPM을 SQLite로 설정했고, nginx 가상 호스트, SSL 등 모든 것이 정상적으로 작동하고 있습니다. 하지만 Discourse 사이트와 NPM 설정에서 502 오류가 발생하고 있어서, Discourse 데이터베이스를 NPM에 어떻게 연결해야 하는지 확인하고 싶습니다.

제 docker-compose 파일은 다음과 같습니다.

version: "3"
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: always
    network_mode: bridge    <-- 이 네트워크를 추가하여 NPM이 Discourse와 동일한 네트워크에 있도록 했고, 이제 서로를 인식합니다.
    ports:
      # Public HTTP Port:
      - '80:80'
      # Public HTTPS Port:
      - '443:443'
      # Admin Web Port:
      - '81:81'
    environment:
      DB_SQLITE_FILE: "/data/database.sqlite"
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt

아니요, 제 추천은 무엇을 하고 있는지 정확히 아는 경우가 아니라면 NPM의 표준 설정을 사용하라는 것입니다. 그래서 저는 표준 설정을 사용하고 있습니다.

websocket을 통해 discourse 컨테이너를 연결하는 경우 3단계는 필요하지 않습니다.

이것은 다음과 같은 이유 때문입니다.

172.17.0.2가 당신의 db 컨테이너인지 확실합니까? - 어쨌든: NPM을 자체 네트워크에 두고 websocket을 통해 discourse에 연결하면 이 문제를 피할 수 있습니다.

2개의 좋아요

@tophee님, 설명해 주셔서 감사합니다. 말씀하신 대로 모든 작업을 수행하고 수정했지만, 웹소켓을 사용하지 않았으며 npm 설정과 Discourse 컨테이너의 포트에 집중하고 있었습니다.

NPM에서 겪은 문제는 CloudFlared Argo 터널과 관련이 있었습니다. NPM, SSL 등 모든 설정을 마친 후 CloudFlared Argo 터널을 실행할 수는 있었지만, CloudFlared는 보조 프록시로 실행할 수 없으며, 원본 웹 앞에 NPM을 두지 않도록 해야 한다는 점이 문제였습니다. CloudFlare에서 발생한 오류는 다음과 같습니다:

Error 1000: DNS points to prohibited IP

Cloudflare에서 해당 오류를 검색해 보니 다음과 같은 안내가 나타났습니다.

There is a reverse-proxy at your origin that sends the request back through the Cloudflare proxy. Instead of using a reverse-proxy, contact your hosting provider or site administrator to configure an HTTP redirect at your origin.

NPM을 리버스 프록시로 비활성화하는 방법은 무엇일까요?

제가 원하는 것은 NPM이 설치되어 있고 정상적으로 작동하는 상태에서도 NPM 없이 원본 IP가 작동하도록 하는 것입니다. 이렇게 하면 CloudFlared가 서버와 통신할 수 있을까요?

1개의 좋아요

NPM을 삭제하세요. NPM의 존재 이유는 리버스 프록시로 작동하는 것이기 때문입니다. 리버스 프록시를 원하지 않는다면 끄면 됩니다.

정확히 어떤 의도인지 이해가 되지 않으며, 이 부분은 제가 전혀 아는 바가 없습니다. 아마도 NPM 포럼이나 관련 자료를 확인해 보시는 것이 좋겠습니다. 이 문제는 discourse와 무관합니다.

2개의 좋아요

거기서 이미 열어 두었고, 여기에서도 논의하고 있습니다. 그리고 네, 2일 동안 이것저것 테스트해 본 후 비활성화했습니다. 하지만 이 주제는 NPM과 함께 소켓 nginx만 지원하므로, Discourse와 NPM에서 사용자 지정 포트 지원을 어떻게 추가하는지 여기에 추가하고 싶습니다.

감사합니다.

1개의 좋아요

아니요. 소켓 지침을 따르지 않는 한 소켓만 지원하는 것은 아닙니다. 소켓을 사용할 필요가 없다고 명시되어 있습니다:

마지막으로 이 기능을 테스트했을 때, 제안된 대로 포트를 사용하여 정상적으로 작동했습니다.

1개의 좋아요

이 안내 덕분에 Nginx Proxy Manager와 함께 Discourse를 설정할 수 있었습니다.
하지만 http에서 폰트와 이미지를 로드하려고 할 때 브라우저에서 “혼합된 콘텐츠(mixed content)” 오류가 발생합니다.

아래 옵션을 통해 링크에서 "https 강제(force https)"를 설정할 수 있습니다:

1개의 좋아요

와, 정말 복잡하고 조건이 많은 주제네요.

오늘 저도 직접 설정을 시도해 봤는데, 아쉽게도 완전히 실패했습니다. 설명서에는 좋은 의도가 담겨 있지만, 제 생각에는 그렇게 쉽게 이해하거나 파악하기 어렵습니다.

Docker를 사용할 때 저는 보통 컨테이너들이 서로 격리되어 독립적으로 실행되기를 원합니다. 의존성, 사전 요구 사항, 그리고 "단일 장애점"이 너무 많지는 않기를 바랍니다. 그런데 이 접근 방식은 바로 이런 문제들을 야기합니다. NPM은 훌륭한 도구입니다. 왜 Proxy Manager의 Docker 구성을 특별히 수정해서야 비로소 Discourse가 만족하고 인증서를 제공할 수 있는지 이해할 수 없습니다. 제 가정에서도 NPM을 DynDNS 도메인에 사용하고 있어 언제든 서비스와 호스트를 유연하게 할당할 수 있습니다. 그리고 그중 일부(Home Assistant, Grafana 등)는 공개적으로 사용하기도 합니다.

오늘은 제 두 개의 Discourse 인스턴스를 통합하려 했습니다. Hetzner(독일)에서 클라우드 서버를 특별히 임대했습니다. 그래서 설명서가 전제하듯 Discourse가 미리 설치되어 있지 않았습니다.

Discourse가 기본적으로 NPM 설치를 공식적으로 제공해 주었으면 좋겠습니다. 아니면 최소한 ./discourse-setup 스크립트로 이렇게 많은 문제를 만들지 않았으면 좋겠습니다.

1개의 좋아요

여러 인스턴스를 설치하는 간단한 방법입니다 :disguised_face:

이 글에서는 깨끗한 서버 설치를 시작하고, 이후에 이전 인스턴스를 복원하는 과정을 다룹니다.

0단계: 백업!!!

백업을 다운로드하세요. 나중에 필요할 것입니다.

1단계: NGINX Proxy Manager

mkdir -p /opt/nginx-proxy-manager
cd /opt/nginx-proxy-manager
nano docker-compose.yml
version: '3'
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: always
    ports:
      - '80:80'    # http / 예약됨! 
      - '81:81'    # 웹 관리 포트
      - '443:443'  # https / 예약됨!  
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt

마지막으로: docker-compose up -d

(나처럼 때로는 더 게으른 사람들을 위해, casaOS를 사용해도 됩니다 (80/81/443 포트 이외의 포트 사용). 보안 로그인 자격 증명을 사용하고, SSL 인증서가 포함된 추가 프록시 호스트를 설정하여 보안 계층을 한층 더 강화하세요. 자신이 무엇을 하는지 안다면 방화벽 규칙도 설정할 수 있습니다.

2단계: Ubuntu 서버에 Docker 설치

sudo apt update && apt upgrade -y

sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

sudo apt update
sudo apt-get install docker-ce docker-ce-cli containerd.io

3단계: Discourse 설치 준비

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

cp /var/discourse/samples/standalone.yml /var/discourse/containers/app1.yml
nano /var/discourse/containers/app1.yml

cp /var/discourse/samples/standalone.yml /var/discourse/containers/app2.yml
nano /var/discourse/containers/app2.yml

app.yml 파일에 필요한 변경 사항을 적용하세요. 여기에는 각 인스턴스에 대한 서로 다른 공개 포트(네, 유지보수에 사용할 수도 있습니다), 메일 설정 등이 포함됩니다.

예를 들어 app1에는 http/https를 위해 포트 8080/1443을, app2에는 포트 8081/2443을 지정합니다.

/var/discourse/launcher rebuild app1
/var/discourse/launcher rebuild app2

4단계: 마지막으로 NGINX Proxy Manager 구성

NGINX Proxy Manager 사용법을 기본적으로 이해하려면 아래 영상을 참고하세요.

해야 할 일은 프록시 호스트 항목을 각 인스턴스(http 포트, 예: 로컬 또는 공용 IP와 함께 8080 및 8081, 선택은 당신에게 달려 있습니다)로 지시하는 것뿐입니다. 그러면 각 인스턴스 및 도메인에 대해 무료 Let’s Encrypt 인증서를 발급받을 수 있습니다. Force SSL 등을 활성화하는 것을 잊지 마세요.

5단계: 완료. 커피 한 잔을 드세요.

제 경우에는 완벽하게 작동합니다.

사전 설치된 소프트웨어 종속성 관련으로 약간의 문제가 있을 수 있지만, 해결책을 찾으실 수 있을 것입니다. 제가 casaOS 팁을 드린 것에 화내지 마세요. 하지만 서버를 가지고 노는 것을 좋아하고, 사용 가능한 모든 리소스를 안전하고 보안이 보장되며 쉽게 사용할 수 있는 방식으로 활용하기를 원하는 분들에게는 이 Docker 관리 방식이 흥미로울 것이라고 확신합니다.

6단계: 마지막으로, 이전 백업을 복원하세요.

1개의 좋아요

클라우드플레어 터널을 도메인에 사용하면서 이걸 결합할 수 있을까요?

1개의 좋아요

좋아, 왜 안 되겠어?

다만, Cloudflare 터널에서 올바른 포트를 노출하고 해당 도메인에 대해 이 포트를 설정해야 한다는 점을 꼭 확인해.

개인적으로 이 솔루션을 선호하지 않아. Cloudflare에 종속적이게 되며, 각 터널 에이전트는 내 방화벽에 구멍 :hole:을 내기 때문에 마치 트로이 목마를 설치하는 것 같은 느낌이 들거든.

방화벽 관리는 서버 관리자에게 필수적이야. 사이트를 DMZ에 노출하기 전에 해야 할 숙제가 좀 있을 거야.