РЕДАКТИРОВАНО: @pfaffman переписал это как отдельную тему на основе того, что ранее написал @tophee. Это ещё не проверено мной, и я переместил слова Криса, поэтому любые ошибки, скорее всего, являются ошибками @pfaffman.
Есть ли причины не использовать NGINX Proxy Manager вместо того, чтобы делать это вручную, как описано в Run other websites on the same machine as Discourse?
Я уже использую его. У меня он работает на домашнем сервере уже какое-то время, и когда я мигрировал свой экземпляр Discourse на новый облачный сервер, я понял, что забыл большую часть настройки обратного прокси NGINX, которую я делал 4 года назад на старом сервере. Тогда я подумал: почему бы не сделать это с помощью NGINX Proxy Manager? К моему удивлению, я обнаружил, что здесь на meta о нём упоминают довольно редко, и я начал задумываться, не упустил ли я какие-то недостатки…
Действительно, это потребовало немного проб и ошибок, но я заставил это работать следующим образом (без гарантии, что это лучший способ — на самом деле я знаю, что должен быть лучший способ — поэтому исправления и улучшения очень приветствуются):
Для начала есть два способа доступа к вашему экземпляру Discourse: 1. через открытие порта, 2. через веб-сокет. Я где-то на этом форуме узнал, что веб-сокет быстрее и эффективнее, поэтому я использую его, но открытие порта должно быть намного проще. Так что, если у вас не получится настроить сокет, попробуйте открыть порт. Чтобы избежать путаницы: для доступа к Discourse через порт выполните шаги 0, 1, 2, 3, 4 и 8 ниже. Если вы хотите использовать веб-сокет, выполните шаги 0, 1, 5, 6, 7, 8 и 9.
0. Исходная точка
Предположим, вы завершили стандартную 30-минутную установку и предположим, что вы ещё не позволили Discourse получить сертификат Let’s Encrypt, потому что он не нужен при использовании обратного прокси. Этим займётся NGINX Proxy Manager. Впрочем, не имеет значения, есть ли у вас уже сертификат. NGINX Proxy Manager просто получит новый.
1. Установка NGINX Proxy Manager
Следующий шаг — установить NGINX Proxy Manager, чтобы у вас работали ещё два контейнера Docker (NGINX Proxy Manager и его контейнер базы данных).
Далее следует сложная часть, о которой вы спрашиваете.
Первое препятствие: Discourse работает в сети Docker bridge по умолчанию, тогда как NGINX Proxy Manager по умолчанию работает в сети «созданной пользователем» (в моём случае она называется npm_default). Это означает, что NGINX Proxy Manager не видит Discourse. ![]()
2. Перемещение всех контейнеров в сеть bridge по умолчанию
Пока я не знаю, можно ли и как переместить Discourse в пользовательскую сеть, нам придётся переместить NGINX Proxy Manager в сеть bridge по умолчанию. Это можно сделать, добавив network_mode: bridge к обоим контейнерам NGINX Proxy Manager в нашем файле docker compose.
3. Использование IP-адреса вместо имени сервиса
Следующая проблема: стандартный файл docker compose больше не будет работать, если просто переместить его в сеть bridge. NGINX Proxy Manager больше не сможет найти свой контейнер базы данных. Это потому, что внутреннее разрешение DNS для имён сервисов (на которое полагается файл docker-compose) доступно только в пользовательских сетях, а не в сетях Docker по умолчанию. Поэтому нам придётся прибегнуть к жёстко заданным IP-адресам (именно поэтому это точно не оптимальное решение, так как оно сломается, если IP-адреса ваших контейнеров изменятся). Вам нужно запустить контейнер, даже зная, что он не заработает, записать IP-адрес контейнера базы данных NGINX Proxy Manager и заменить DB_MYSQL_HOST: "db" в вашем файле docker compose на DB_MYSQL_HOST: "<ip_адрес_контейнера_db>".
Теперь все контейнеры должны быть в сети bridge по умолчанию, чтобы NGINX Proxy Manager мог видеть и Discourse, и его базу данных.
4. Сделать Discourse доступным
Но «видеть» Discourse и иметь возможность получить к нему доступ — это не одно и то же. Поэтому вам нужно убедиться, что Discourse примет любой трафик, который NGINX Proxy Manager пересылает ему. Если вам не важно использовать веб-сокет, я полагаю, вы можете просто указать NGINX Proxy Manager на порт 80 (не 443) IP-адреса вашего контейнера Discourse, как это:
Однако я это не проверял. Как я уже упоминал, я использую настройку веб-сокета, которая требует дополнительных шагов. Обратите внимание, что имя хоста/IP и порт выше будут игнорироваться при использовании веб-сокета.
5. Настройка app.yml для использования веб-сокета
Это объясняется в исходном посте, поэтому я не буду вдаваться в подробности.
6. Подключение веб-сокета в контейнере NGINX Proxy Manager
Нам нужно предоставить NGINX Proxy Manager доступ к веб-сокету, смонтировав его как том: - /var/discourse/shared/standalone/nginx.http.sock:/var/discourse/shared/standalone/nginx.http.sock. Это последнее изменение в стандартном файле docker compose для NGINX Proxy Manager, поэтому вот финальная версия, которая работает у меня:
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. Настройка NGINX Proxy Manager для использования веб-сокета
Последний шаг: скажите NGINX Proxy Manager использовать веб-сокет. Насколько я помню, просто включить «Поддержку веб-сокетов» было недостаточно, поэтому я скопировал расположение NGINX из исходного поста на вкладку «Дополнительно», как это:
У меня это не сработало на вкладке «Пользовательские расположения».
8. Не забудьте активировать SSL
Я не упоминал конфигурацию SSL в NGINX Proxy Manager, потому что это кажется вполне очевидным, и я не думаю, что имеет значение, на каком этапе процесса вы её активируете. Так что, если вы ещё не сделали этого, вот как выглядит моя настройка:
9. Внимание
tl;dr: Каждый раз при перезапуске контейнера Discourse вам также нужно перезапускать основной контейнер NGINX Proxy Manager (перезапускать db не нужно).
Если вы получаете доступ к Discourse через веб-сокет, имейте в виду, что при пересборке контейнера Discourse (что требуется каждые несколько месяцев для обновления базового образа) предыдущий веб-сокет будет удалён, а создан новый. В результате NGINX Proxy Manager потеряет связь с вашим экземпляром Discourse и выдаст ошибку 502. Возможно, в будущем обновлении NGINX Proxy Manager сможет автоматически находить новый веб-сокет, но на данный момент (январь 2022 года) NGINX Proxy Manager не найдёт ваш пересобранный контейнер Discourse, если вы не перезапустите NGINX Proxy Manager.
Объяснение
Если вы спрашиваете, почему в приведённых выше инструкциях веб-сокет сочетается с портами, причина проста: когда я писал этот пост, мне внезапно пришло в голову, что NGINX Proxy Manager и Discourse, вероятно, даже не должны находиться в одной сети Docker, когда мы используем веб-сокет. И когда это было подтверждено, никто не почувствовал необходимости полностью переписывать инструкции.
Это самый увлекательный аспект форумов поддержки: хорошее описание вашей проблемы часто приводит вас к решению, даже не публикуя ваш вопрос. И в данном случае я отвечал на чей-то вопрос, но также, возможно, нашёл ответ на свой собственный. ![]()



