Используйте Nginx Proxy Manager для управления несколькими сайтами с Discourse

Действительно, это потребовало немного проб и ошибок, но я добился успеха следующим образом (без гарантий, что это лучший способ — на самом деле я знаю, что должен быть лучший — поэтому исправления и улучшения очень приветствуются):

Инструкции, которые @pfaffman перенес в исходный пост

Для начала есть два способа доступа к вашему экземпляру Discourse: 1. путем открытия порта, 2. через веб-сокеты. Я где-то на этом форуме узнал, что веб-сокеты быстрее/эффективнее, поэтому использую их, но открытие порта должно быть намного проще, так что если у вас не получится настроить сокет, попробуйте открыть порт (подробнее об этом ниже).

Итак, предположим, что вы завершили стандартную 30-минутную установку и предположим, что вы еще не дали Discourse получить сертификат Let’s Encrypt — потому что при использовании обратного прокси он вам не нужен. NPM позаботится об этом. Неважно, если у вас уже есть сертификат. NPM просто получит новый.

1. Установка NPM

Следующий шаг — установка NPM, чтобы у вас было запущено еще два контейнера Docker (NPM и его контейнер базы данных).

Далее идет сложная часть, о которой вы спрашиваете.

Первое препятствие: Discourse работает в сети bridge Docker по умолчанию, а NPM по умолчанию работает в сети, созданной пользователем (в моем случае npm_default), что означает, что NPM не видит Discourse. :cry:

2. Переместите все контейнеры в сеть bridge по умолчанию

Пока я не знаю, можно ли и как переместить Discourse в пользовательскую сеть, нам придется переместить NPM в сеть bridge по умолчанию. Это можно сделать, добавив network_mode: bridge к обоим контейнерам NPM в нашем файле docker compose.

3. Используйте IP-адрес вместо имени службы

Следующая проблема: стандартный файл docker compose перестанет работать, если просто переместить его в сеть bridge. NPM больше не сможет найти свой контейнер базы данных. Это связано с тем, что внутреннее разрешение DNS для имен служб (на которое опирается файл docker-compose) доступно только в пользовательских сетях, а не в сетях Docker по умолчанию. Поэтому нам придется использовать жестко заданные IP-адреса (поэтому это определенно не оптимальное решение, так как оно сломается, если IP-адреса ваших контейнеров изменятся). Итак, вам нужно запустить контейнер, даже зная, что он не будет работать, записать IP-адрес контейнера базы данных NPM и заменить DB_MYSQL_HOST: "db" в вашем файле docker compose на DB_MYSQL_HOST: "<ip_адрес_контейнера_db>".

Теперь все контейнеры должны быть в сети bridge по умолчанию, чтобы NPM мог видеть и Discourse, и его базу данных.

4. Сделать Discourse доступным

Но «видеть» Discourse и иметь возможность к нему обращаться — это не одно и то же. Поэтому вам нужно убедиться, что Discourse примет любой трафик, который NPM пересылает ему. Если вам не важно использовать веб-сокеты, я полагаю, вы можете просто указать NPM на порт 80 (не 443) IP-адреса вашего контейнера Discourse, например:

Хотя я это не тестировал. Как я уже упоминал, я использую настройку веб-сокетов, которая требует дополнительных шагов. Обратите внимание, что имя хоста/IP и порт выше будут игнорироваться при использовании веб-сокетов.

5. Настройка app.yml для использования веб-сокетов

Это объяснено в исходном посте, поэтому я не буду вдаваться в подробности.

6. Подключите веб-сокеты в контейнере NPM

Нам нужно предоставить NPM доступ к веб-сокетам, подключив его как том: - /var/discourse/shared/standalone/nginx.http.sock:/var/discourse/shared/standalone/nginx.http.sock. Это последнее изменение в стандартном файле docker compose NPM, поэтому вот финальная версия, которая работает у меня:

version: '3'
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    network_mode: bridge
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
    environment:
      DB_MYSQL_HOST: "172.17.0.6"
      DB_MYSQL_PORT: 3306
      DB_MYSQL_USER: "npm"
      DB_MYSQL_PASSWORD: "my-super-safe-pwd"
      DB_MYSQL_NAME: "npm"
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
      - /var/discourse/shared/standalone/nginx.http.sock:/var/discourse/shared/standalone/nginx.http.sock
  db:
    image: 'jc21/mariadb-aria:latest'
    restart: unless-stopped
    network_mode: bridge
    environment:
      MYSQL_ROOT_PASSWORD: 'my-super-safe-pwd'
      MYSQL_DATABASE: 'npm'
      MYSQL_USER: 'npm'
      MYSQL_PASSWORD: 'my-super-safe-pwd'
    volumes:
      - ./data/mysql:/var/lib/mysql

7. Настройка NPM для использования веб-сокетов

Последний шаг: скажите NPM использовать веб-сокеты. Насколько я помню, недостаточно просто включить «Поддержку веб-сокетов», поэтому я скопировал NGINX location из исходного поста на вкладку «Дополнительно», вот так:

У меня не получилось это сделать на вкладке «Пользовательские location».

8. Не забудьте активировать SSL

Я не упоминал настройку SSL в NPM, потому что это кажется вполне очевидным, и я не думаю, что имеет значение, на каком этапе процесса вы её активируете. Так что если вы еще этого не сделали, вот как выглядит моя настройка:


9. Финальное предупреждение

Пока я писал этот пост, мне вдруг пришло в голову, что NPM и Discourse, вероятно, даже не должны находиться в одной сети Docker, когда мы используем веб-сокеты. У меня сейчас нет времени это проверить, но если это так, то вы можете просто забыть о шагах 2, 3 и 4 выше, и всё должно работать.

Это самый захватывающий аспект форумов поддержки: качественное описание своей проблемы часто приводит к решению, даже не публикуя свой вопрос. И в данном случае я отвечал на чужой вопрос, но, возможно, также нашел ответ на свой собственный. :smiley:

4 лайка