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

РЕДАКТИРОВАНО: @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. :cry:

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, когда мы используем веб-сокет. И когда это было подтверждено, никто не почувствовал необходимости полностью переписывать инструкции.

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

9 лайков

Обсуждение того, какой обратный прокси следует использовать, явно выходит за рамки поддерживаемых вопросов. :wink: Но после изучения NGINX Proxy Manager в течение 12 секунд или более я думаю, что он справится. Я также видел обсуждение другого автоматического инструмента проксирования на базе NGINX, но, учитывая мои огромные знания о NGINX Proxy Manager, мне кажется, что он может быть лучше. Возможно, я посмотрю на него, так как я начинаю разочаровываться в Traefik.

РЕДАКТИРОВАНИЕ: Теперь я изучил его в течение 3 минут. Я предпочитаю инструменты, которые упрощают автоматизацию, поэтому Traefik и jwilder/nginx-proxy - Docker Image (я его нашел), которые позволяют добавлять метки или переменные окружения к контейнеру Docker, чтобы не нужно было кликать в веб-интерфейсе, больше соответствуют моим потребностям. Похоже, что для работы этого инструмента нужно использовать веб-интерфейс или вручную обновлять базу данных, добавляя хосты, которые вы хотите включить. Но если вы готовы кликать и возиться в веб-интерфейсе как обычный человек (а не как системный администратор), то, похоже, этот инструмент может быть именно тем, что вы ищете.

4 лайка

Я пытался установить Nginx Proxy Manager, но не понимаю, как «связать» (через прокси? извините, я довольно новичок в системном администрировании) контейнер Discourse, чтобы видеть Discourse при доступе через веб-браузер.
Можете ли вы дать несколько подсказок? Должен ли контейнер Discourse открывать порты 80 и 443 или нет, как предлагается в этой теме форума?

1 лайк

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

Инструкции, которые @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 лайка

Большое спасибо за отличный и чёткий ответ! Я попробую ваши советы как можно скорее. Кстати, какие IP-адреса нужно указывать в NPM: адреса сервера (то есть внешний IP для доступа к серверу) или внутренние адреса Docker (я заметил, что Docker использует 172… для контейнеров)?
Извините, если вопросы кажутся тривиальными, я не очень хорошо разбираюсь в сетевых вопросах.

1 лайк

Рекомендую использовать WebSocket. Тогда вы можете указать любой IP, так как он не будет использоваться. В противном случае нужно указывать внутренний IP контейнера, а не публичный IP хоста.

Кстати: похоже, ваш ответ по электронной почте отобразился некорректно. Возможно, стоит отредактировать (сократить) свой пост выше?

2 лайка

Да, я видел. Я использовал «Ответить» из письма, и оно попыталось вставить всё исходное сообщение, но я не могу найти способ его изменить. Возможно ли это? Я новичок в Discourse даже как пользователь… :pensive:

1 лайк

Вы можете редактировать свои сообщения, используя значок карандаша в нижней части вашего сообщения. Однако… Уровень доверия 1 и ниже получают 24 часа (по умолчанию), тогда как Уровень доверия 2 и выше получают 30 дней (по умолчанию).

Похоже, что вы сейчас находитесь на уровне TL1 Basic, но вы можете узнать больше о том, что нужно сделать, чтобы «повысить уровень», в статье Уровни доверия. :+1:

2 лайка

Извините, если прошло много времени с момента предыдущего вопроса, но я потратил очень много времени, пытаясь сделать то, что вы посоветовали, — без какого-либо успеха. Когда я изменил app.yml и пересобрал приложение с вашими изменениями, в логах стало появляться сообщение «config/unicorn_launcher: line 71: kill: (898) - No such process», и как бы я ни пытался, этот процесс не удаётся остановить. Я также пробовал пересобрать приложение в его исходном состоянии (с открытыми портами, без веб-сокетов), останавливал npm, но безрезультатно: «unicorn» не запускается.

Я также пробовал следовать всем рекомендациям, которые находит Google (кажется, это распространённая проблема), но так и не смог понять, как собрать рабочий контейнер Discourse. Сейчас проблема в том, что (одна из самых серьёзных, я почти готов сдаться с Discourse) по какой-то запутанной и непонятной причине внутренний PostgreSQL постоянно «перезапускается».

Я не знаю почему: я просто внес ваши изменения, пересобрал приложение, и с этого момента «unicorn» :roll_eyes — мёртв.

Есть ли способ исправить эту проблему с PostgreSQL? Почему это произошло? Есть ли шанс (я боюсь, что нет!) не потерять все изменения, которые я внёс в Discourse, когда он ещё работал?

Кстати, нормально ли то, что каждое маленькое изменение или попытка что-то исправить приводит к тому, что что-то другое перестаёт работать? :rage:

Я не злюсь на вас: дело не в ваших советах, а в самом Discourse. Я потратил очень много времени, пытаясь заставить этот «вроде бы» хороший форум работать, но каждый раз что-то идёт не так. Мои ощущения, что Discourse крайне ненадёжен, становятся всё сильнее.

1 лайк

Если у вас была стандартная рабочая установка, вы должны быть в состоянии вернуть всё как было, и всё продолжит работать.

Проблема с PostgreSQL может быть связана с обновлением PostgreSQL 13?

Если вы сделали резервную копию перед началом, вы можете установить на новый сервер и восстановить эту резервную копию. Это должен быть наихудший сценарий.

2 лайка

Как я могу узнать, связана ли проблема с PostgreSQL с обновлением до версии 13? Я не выбирал обновление вручную — я просто ввёл ./launcher rebuild app, и всё пошло не так.
Да, это версия 13. После нескольких часов чтения в интернете о том, как у других возникли аналогичные проблемы, я понял, что это может быть причиной, но так и не нашёл способа оживить Discourse.

1 лайк

Тогда это не проблема. Извините.

1 лайк

Мне очень жаль, что у вас возникли такие проблемы. Я понимаю это разочарование, когда тратишь часы на попытку что-то исправить. Но каждый раз чему-то учишься, даже если путь к решению редко бывает прямым…

Извините, но я не тот человек, кто может помочь вам в этом вопросе. У меня нет опыта работы с PostgreSQL или Unicorn. Я обычно прохожу через такие ситуации, когда «ничего не работает», тремя способами: 1. Делаю резервную копию, чтобы всегда можно было вернуться к исходному состоянию. 2. Пробую или меняю только одну вещь за раз и сначала тестирую это на нересурсной машине (или на менее важном форуме). 3. Тратлю ещё больше времени, пытаясь разобраться в ситуации.

Кстати: подробное описание проблем или создание заявок на поддержку более одного раза помогало мне решить проблему. Иногда мне даже не приходилось отправлять заявку. Само написание описания заставляло меня увидеть решение.

Так что в вашем случае я бы попытался понять: при каких обстоятельствах изменение файла app.yml с последующим возвратом к исходному состоянию приводит к результату, отличному от первоначального. При изучении этого вы либо поймёте, что не восстановили точную исходную версию, либо осознаете, что ещё нужно «сбросить», чтобы всё заработало.

5 лайков

Мне очень жаль, но я не понимаю: сначала вы спросили, может ли проблема с PostgreSQL быть связана с обновлением до версии 13, и когда я ответил «да, это версия 13» (клянусь, я не знал, какая была раньше, прошло много времени с тех пор, как я не пересобирал приложение), вы ответили, что это не проблема… так почему же PostgreSQL всегда находится в состоянии «запуска», а Discourse не запускается?

1 лайк

Привет, @Wanderer. Я не могу точно сказать, в чём может быть ваша проблема, поэтому обновление PostgreSQL было лишь предположением. Я почти уверен, что если вы используете PostgreSQL 13, то проблема не в том, что вы застряли на этапе обновления с версии 10 или 12. Хотя возможны какие-то неполадки с PostgreSQL, они, скорее всего, не связаны с обновлением до версии 13.

Моя лучшая рекомендация для тех, кто не является экспертом в этих вопросах, — выполнить чистую установку и восстановить последнюю резервную копию.

Если вы хотите получить более конкретную помощь по вашей проблеме и у вас есть бюджет, вы можете связаться со мной или написать в канал Marketplace.

Я планирую улучшить инструкции для Nginx Proxy Manager, но, скорее всего, ваша проблема, хотя и проявилась при попытке перейти к такой сложной настройке, не вызвана ошибками в этих инструкциях. (Я не знаю наверняка, но это моё наилучшее предположение.)

2 лайка

Вот моя версия этого решения. Я почти сдался, но @tophee дал ссылку на пост, который (!?) написал я сам и который содержал необходимое «магическое» решение! Теперь это простой способ настроить Nginx Proxy Manager для Discourse. Я считаю, что это делает процесс похожим на описанный здесь: Run other websites on the same machine as Discourse - #396.

Установите Nginx Proxy Manager согласно их инструкциям по адресу:

Удалите шаблоны SSL и Let’s Encrypt:

Убедитесь, что следующие строки в вашем файле yml закомментированы или удалены:

## Раскомментируйте эти две строки, если хотите добавить Lets Encrypt (https)
#- "templates/web.ssl.template.yml"
#- "templates/web.letsencrypt.ssl.template.yml"

Настройте Discourse для использования сети npm-default.

Если слепо следовать инструкциям по установке Nginx Proxy Manager, будет создана docker-сеть с именем npm_default.

Добавьте этот блок в ваш файл (файлы) yml. Если у вас есть отдельные контейнеры web_only и data, вам нужно добавить это в каждый из них (я не тестировал контейнер mail-receiver). docker_args не должен быть отступом.

docker_args: |
  --network npm_default

Нет необходимости открывать какие-либо порты

Закомментируйте или удалите эти строки из вашего файла yml:

# expose:
#  - "80:80"   # http
#  - "443:443" # https

Затем вы можете пересобрать свой(е) контейнер(ы) и настроить Nginx Proxy Manager следующим образом:

image

Простой (но не обязательно рекомендуемый) способ запустить второй сайт Discourse выглядит так:

cd /var/discourse/containers
cp app.yml othersite.yml
# как-то отредактируйте, как минимум, имя хоста в othersite.yml
./launcher rebuild othersite

Затем добавьте его в NPM, как описано выше, используя othersite вместо app.

Я тестировал это с app.yml плюс двумя контейнерами типа web_only и одним контейнером data, а также отдельным контейнером othersite-redis, который является копией контейнера data, содержащей только шаблоны redis. (Но более простое решение — поместить дополнительный redis в контейнер web_only).

2 лайка

Итак, после некоторых трудностей мне удалось заставить всё работать.

Хочу сразу оговориться: хотя я разработчик «старой школы» (родился в 1980 году), я всегда искал лучшие и новейшие способы разработки и управления системами. Поэтому в 2021 году я искренне ненавижу писать странные команды, наполненные загадочными опциями, как это было в эпоху CP/M и DOS. Я всегда стремлюсь к интерфейсам, которые делают мою жизнь проще и понятнее.

Например, я использую Portainer для управления контейнерами. Он позволяет запускать, останавливать, редактировать и дублировать все контейнеры на лету, без необходимости «рыться» в файловой системе в поисках уникального файла. Например, чтобы изменить сеть контейнера, достаточно выбрать её из списка и сделать один клик; то же самое касается добавления параметров или томов, как в примере, который привёл @tophee. По этой причине я решил попробовать NPM, так как предпочитаю «контейнеризировать» свой прокси Nginx и потому, что, судя по всему, это делается всего несколькими кликами: вы хорошо понимаете, что делаете, но вам не нужно запоминать новый набор странных команд и опций.

Вернёмся к моему контейнеру Discourse. Мне пришлось снова выполнить настройку через discourse-setup. Всё прошло успешно: «злой» Postgres установился в версии 13, никакого «пьяного единорога» (извините, но мысль о «единороге», бегущем на моём сервере, заставляет меня смеяться! :laughing:), короче говоря, всё прошло гладко. Затем я внёс изменения, чтобы Discourse работал с веб-сокетами: и на этот раз всё прошло отлично. К счастью, предыдущая настройка Discourse создавала автоматические резервные копии, поэтому всего несколькими кликами я восстановил всё (чем больше я использую Discourse, тем больше он мне нравится!).

Настройки для NPM мне пришлось пробовать несколько раз: сначала возникли проблемы с сертификатами, но в конце концов и он заработал без сбоев.

Я добавил второй прокси, указывающий на мой контейнер WordPress (да, я «контейнеризировал» всё, мне нравится идея максимально чистого сервера, где все основные пакеты находятся в управляемом месте), и он тоже работает отлично.

В итоге у меня есть сервер (VPS) со своим почтовым сервером (я также пытался «контейнеризировать» его, но после недель ожесточённой борьбы сдался), Discourse, указывающий на него, WordPress, работающий в отдельном контейнере, и NPM, управляющий обоими. Всё это на моём сервере, без зависимости от других (и гораздо, гораздо более дорогих) сервисов для развёртывания, отправки почты и т. д.

Следующий шаг — импорт нескольких сотен тысяч постов из «старого доброго phpBB»: готовьтесь к новым моим постам! :grinning_face_with_smiling_eyes:

Огромное спасибо @tophee и @pfaffman за помощь. Я понимаю, насколько сложно помогать людям, которые работают нестандартным образом, как я.

3 лайка

Рад, что вам удалось заставить это работать через WebSocket. Для всех остальных, кто с этим сталкивается, рекомендую воспользоваться инструкциями @pfaffman по выполнению этой задачи без WebSocket, приведёнными выше.

Я не знаю, что именно вызвало вашу проблему, но мне кажется, что стоит прояснить этот момент для всех, кто относительно недавно занимается администрированием Discourse: необходимо понимать, как работает сертификат Let’s Encrypt в стандартной установке (без внешнего прокси) и как он работает с NPM (а если вы задаётесь вопросом, почему его называют внешним прокси, вам тоже нужно в этом разобраться).

Поскольку я изначально настраивал свой внешний прокси вручную, а также вручную настраивал Let’s Encrypt, я понимал всю «магию», которую Discourse и NPM выполняют за вас, чтобы HTTPS работал корректно. Благодаря этому мне удалось избежать различных подводных камней при переходе с сертификатов, управляемых Discourse, на сертификаты, управляемые NPM.

Я не совсем понимаю, зачем вам нужно размещать почтовый сервер за NPM…

1 лайк

Нет, Кристоф, не за NPM, а просто в контейнере. Я пробовал Zimbra, но это было огромным хаосом. Затем простой «контейнеризированный» Postfix, но и там без успеха. В то время я только начинал свой путь в Linux (я всё ещё новичок, но хотя бы в некоторых концепциях администрирования чувствую себя всё увереннее), поэтому я сдался и попробовал установить всё напрямую на сервер. Он запустился без серьёзных проблем, так что я пошёл этим путём, хотя настройка Discourse для работы с моим почтовым сервером была довольно сложной. Но теперь, кажется, всё работает.

2 лайка

Звучит хорошо до момента установки, пока я не застрял на этапе настройки взаимодействия npm с хостом Discourse; вы упоминаете, что нужно указать IP-адрес контейнера с данными в поле mySQL хоста файла compose для npm:

 environment:
      DB_MYSQL_HOST: "db"
      DB_MYSQL_PORT: 3306
      DB_MYSQL_USER: "npm"
      DB_MYSQL_PASSWORD: "npm"
      DB_MYSQL_NAME: "npm"

Но когда я меняю (DB_MYSQL_HOST) на контейнер с данными, появляется ошибка «connection refused».

connect ECONNREFUSED 172.17.0.2:3306 <-- ошибка, когда npm находится в сети Discourse (network_mode: bridge).
getaddrinfo ENOTFOUND db <-- ошибка, когда mySQL в файле compose для npm определен как "db".

Есть какие-то предложения, как заставить шаг 3 работать у меня?

1 лайк