Настройка мультисайта с Let's Encrypt и без обратного прокси

Эти инструкции следует считать бета-версией и они предназначены для тех, кто знаком со стандартной настройкой

Однако прямо сейчас (2023.02.11) эти инструкции не работают! (Смотрите Set up Let’s Encrypt with multiple domains / redirects, чтобы узнать, как обновить настройки letsencrypt и добавить часть fullpath. Я обновлю это, чтобы отразить эти изменения, в самое ближайшее время.)

Я разработал это руководство несколько недель назад, но мне нужно, чтобы кто-то протестировал его и проверил, работает ли оно для других. Пожалуйста, ответьте, если попробуете, и сообщите, работает ли это и есть ли что-то непонятное.

И продолжаем представление…

Это руководство в общих чертах описывает, как настроить мульти-сайтовую конфигурацию с двумя дополнительными хостами (всего 3).

Предполагается, что у вас есть рабочая официальная стандартная установка Discourse или установка с двумя контейнерами (Move from standalone container to separate web and data containers).

Доменное имя для основного сайта

Поддомен для второго сайта

Поддомен для третьего сайта

Пароль базы данных (такой же, как DISCOURSE_DB_PASSWORD) или discourse в app.yml

Для простоты здесь рассматривается основной сайт с именем =domain= и два дополнительных сайта =two=.=domain= и =three=.=domain=. Вы можете использовать любые имена, но в рамках этого шаблона отсутствие разных коротких имен (для имени базы данных и заголовка подфорума) и полного имени хоста немного упрощает задачу.

Добавьте в hooks после плагинов в app.yml или web_only.yml

  before_bundle_exec:
    - file:
        path: $home/config/multisite.yml
        contents: |
         =two=:
           adapter: postgresql
           database: =two=
           pool: 25
           timeout: 5000
           host: data
           password: NThmZTNjZjZhOTczNmVj
           host_names:
             - =two=.=domain=
         =three=:
           adapter: postgresql
           database: =three=
           pool: 25
           timeout: 5000
           host: data
           password: NThmZTNjZjZhOTczNmVj
           host_names:
             - =three=.=domain=

  after_db_migrate:
    - exec: cd /var/www/discourse && sudo -E -u discourse bundle exec rake multisite:migrate

  after_ssl:
   # укажите letsencrypt, какие дополнительные сертификаты нужно получить
    - replace:
        filename: "/etc/runit/1.d/letsencrypt"
        from: /-d =domain= /
        to: "-d =domain= -d =two=.=domain= -d =three=.=domain="
        global: true
   # не перенаправляйте все хосты обратно на основное доменное имя
    - replace:
        filename: "/etc/nginx/conf.d/discourse.conf"
        from: /if \(\$http_host[^\}]*\}/m
        to: ""

Добавьте в секцию after_postgres в app.yml или data.yml

  - exec: sudo -u postgres createdb =two= || exit 0
    - exec:
        stdin: |
          grant all privileges on database =two= to discourse;
        cmd: sudo -u postgres psql =two=
        raise_on_fail: false

    - exec: /bin/bash -c 'sudo -u postgres psql =two= <<< "alter schema public owner to discourse;"'
    - exec: /bin/bash -c 'sudo -u postgres psql =two= <<< "create extension if not exists hstore;"'
    - exec: /bin/bash -c 'sudo -u postgres psql =two= <<< "create extension if not exists pg_trgm;"'
    - exec: sudo -u postgres createdb =three= || exit 0
    - exec:
        stdin: |
          grant all privileges on database =three= to discourse;
        cmd: sudo -u postgres psql =three=
        raise_on_fail: false
    - exec: /bin/bash -c 'sudo -u postgres psql =three= <<< "alter schema public owner to discourse;"'
    - exec: /bin/bash -c 'sudo -u postgres psql =three= <<< "create extension if not exists hstore;"'
    - exec: /bin/bash -c 'sudo -u postgres psql =three= <<< "create extension if not exists pg_trgm;"'

После этого выполните:

./launcher rebuild app

или

./launcher rebuild data
./launcher rebuild web_only
10 лайков

Я только что попробовал, причём дважды, потому что не мог поверить, что всё сработало без проблем с первого раза :smile: Всё, что я сделал — скопировал, изменил домены и пароль, а затем вставил в соответствующие файлы свежей установки с двумя контейнерами. :ok_hand:

Жду обратной связи, если что-то непонятно. Мне пришлось немного подумать над этим абзацем:

Кажется, что для следования инструкции требуется настройка с двумя контейнерами, но на самом деле это не так. И я не понял, почему ссылка ведёт на пост 48 темы, а не на исходный пост.

2 лайка

Спасибо! Я посмотрю. Оба момента кажутся именно тем видом небрежности, о которой я надеялся, что вы меня предупредите!

РЕДАКТИРОВАНИЕ: Спасибо! Я по небрежности указал своё текущее местоположение в теме о двух контейнерах, поэтому исправил это и изменил формулировку, чтобы было ясно, что это работает с любой корректно установленной версией.

Спасибо!

2 лайка

Привет!
Я начал со стандартной установки Discourse (на DigitalOcean), затем настроил nginx (используя эти инструкции), так как хотел разместить несколько сайтов на Drupal на том же дроплете.
Если я захочу запустить ещё один экземпляр Discourse, стоит ли следовать вышеуказанным инструкциям?

Или лучше использовать этот гайд?

Спасибо!
/Sifaan

Эти инструкции предназначены для случая, когда не используется обратный прокси. Я рекомендую следовать руководству Настройка мультисайта с Docker. Инструкция, на которую вы ссылаетесь, может сработать, но я рекомендую сначала ознакомиться с тем, что изложено здесь.

2 лайка

Спасибо; я заметил, что в этом случае оба сайта будут использовать одну и ту же конфигурацию SMTP :frowning:
есть ли способ обойти это?
или лучше следовать другому руководству (кажется, что потребуется немного поработать, чтобы перенести существующий сайт в сеть Docker)

alternately, возможно ли установить другую кодовую базу, например /var/discourse2?
(это обойдётся мне примерно в 500 МБ, но это того стоит, если это избавит меня от головной боли)

Да.

Не используйте мультисайт.

Да, но вам просто нужно создать установку с двумя контейнерами, а затем создать файл web_only2.yml. (Кажется, что можно иметь два файла в стиле app.yml, но тогда вы будете без необходимости запускать два экземпляра PostgreSQL). Однако, я думаю, что вам понадобятся два экземпляра Redis.

3 лайка

Спасибо. Так как я не очень хорошо разбираюсь в разделении контейнеров с данными и веб-сервером, я создал отдельный контейнер, следуя этим рекомендациям (и сертификаты, созданные certbot, вроде бы работают). Однако сейчас возникла проблема с настройкой Mailgun: письма активации отправляются на Gmail, но любые письма, хостящиеся у моего регистратора (DreamHost), не доходят :frowning:

Насколько сильно дополнительная инстанция Postgres увеличит нагрузку?
Я ознакомился с вашим постом о разделении и попробую этот вариант, если экономия будет значительной.

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

1 лайк

В последнее время я пытаюсь следовать этой инструкции, но столкнулся с несколькими проблемами:

  1. Я не могу найти пароль от базы данных (или даже понять, для чего он используется в файле).
  2. В моём файле app.yml изначально отсутствовал раздел after_postgres, поэтому я добавил его в секцию hooks, чтобы он соответствовал другим (after_ssl, after_db_migrate и т. д.). Если это размещено в неправильном разделе, пожалуйста, дайте знать — я совершенно новичок в работе с такими вещами.
  3. Когда я проверяю синтаксис YAML-файла на http://www.yamllint.com/, получаю ошибку (<unknown>): did not find expected key while parsing a block mapping на строке, где я добавил секцию after_postgres внутри секции hooks.

Буду очень признателен, если вы сможете уточнить шаги по редактированию файла app.yml.

2 лайка

Возможно, пароль не нужен, если вы используете одноконтейнерную настройку (это предполагается в предыдущем посте).

Добавление раздела, как вы предлагаете, должно сработать.

Я пока не совсем понимаю, что может быть не так. Постараюсь внимательнее разобраться через пару дней.

1 лайк

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

Я думал разместить их на разных доменах. Понимаю, что это может вызвать небольшую путаницу, так как письма будут приходить с одного основного SMTP-адреса. Однако знаете ли вы, создадут ли разные домены какие-либо другие проблемы?

У Discourse есть единый домен для всех бизнес- и стандартных клиентов. Вы можете настроить адрес для уведомлений по электронной почте как угодно, например shortname@whatevermail.com.

2 лайка

Я очень рад это слышать, спасибо!

1 лайк

Привет! Прежде всего, спасибо за туториал.

К сожалению, у меня возникла проблема с запуском дополнительных установок Discourse на одном сервере/IP.
Сначала я следовал документации, чтобы развернуть автономный сайт, и это удалось.
(например, test.john.com — поддомен, перенаправляющий на один IP)
Теперь, когда я попытался добавить ещё одну установку Discourse (например, test.joe.com и test.doe.com — другие поддомены с других сайтов),
я попробовал следовать вашим инструкциям, но это не удалось, и теперь я запутался.

Несколько вопросов:

  1. Как будут установлены эти два дополнительных сайта? Например, скопировать /standalone.yml в директорию containers, переименовать его и выполнить обычную установку? (например, ./launcher rebuild joe)
  2. В ваших инструкциях указано, что изменения должны быть внесены в app.yml, добавив весь код выше — я предполагаю, что это должно быть добавлено в файл первой успешной установки (test.john.com)?

Помимо файлов в директории container, я создал config/multisite.yml, и вот как выглядит мой код:

secondsite:
  adapter: postgresql
  database: b_discourse
  username: postgres
  password: postgres
  host: dbhost
  pool: 5
  timeout: 5000
  host_names:
    - test.joe.com
...
...
# и конфигурация третьего сайта

Однако я не уверен, нужно ли настроить что-то ещё.

Буду благодарен за любой ответ. Спасибо!

Нет. Вы добавляете необходимые строки в app.yml, как описано. Это создаст файл mutlisite.yml внутри контейнера. Будет один экземпляр, и он будет работать для всех доменов, при условии, что DNS для всех них указывает туда. Это не для запуска нескольких контейнеров Discourse, по одному на каждый домен.

На момент последней проверки эти инструкции работали именно так, как написано. Просто добавьте строки в ваш app.yml, и всё должно заработать. Вам не нужно трогать какие-либо другие файлы.

1 лайк

Настройка для одного сайта работает идеально. Проблем нет.
Но я перепробовал множество комбинаций для мультисайта. Один файл app.yml или разделённые web_only.yml, data.yml и т.д. Я также пробовал другие советы на страницах Настройка мультисайта с Docker и Переход от отдельного контейнера к раздельным веб- и дата-контейнерам.

Что касается части миграции, все комбинации всегда завершались ошибкой… >>>> bundle exec rake multisite:migrate

********************** последняя часть процесса **************************
2023-02-11 17:50:43.853 UTC [61] LOG:  shutting down
162:M 11 Feb 2023 17:50:43.866 # User requested shutdown...
162:M 11 Feb 2023 17:50:43.866 * Saving the final RDB snapshot before exiting.
162:M 11 Feb 2023 17:50:43.881 * DB saved on disk
162:M 11 Feb 2023 17:50:43.882 # Redis is now ready to exit, bye bye...
2023-02-11 17:50:44.007 UTC [57] LOG:  database system is shut down


FAILED
--------------------
Pups::ExecError: cd /var/www/discourse && sudo -E -u discourse bundle exec rake multisite:migrate failed with return #<Process::Status: pid 582 exit 1>
Location of failure: /usr/local/lib/ruby/gems/3.1.0/gems/pups-1.1.1/lib/pups/exec_command.rb:117:in `spawn'
exec failed with the params "cd /var/www/discourse && sudo -E -u discourse bundle exec rake multisite:migrate"
bootstrap failed with exit code 1
** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one.
./discourse-doctor may help diagnose the problem.

Я проверил, что было создано, а что нет до момента сбоя.
Базы данных для поддоменов созданы, но миграция не удалась. Конфигурация nginx для поддоменов или файл multisite.yml не были созданы, что я проверил в папках overlay2 или в любом другом месте.

./launcher bootstrap, destroy, start, stop, rebuild или чистая настройка много раз… Пробовал все команды, но ничего не изменилось… :slight_smile:

Актуален ли этот учебник для v3.1.0.beta 2, или что я упускаю?
Есть ли какие-то идеи, пожалуйста?

1 лайк

Нет. Что-то в Let’s Encrypt изменилось в какой-то момент. Я попрошу вас внимательнее посмотреть, какие именно изменения нужно внести внутри контейнера для обработки нескольких доменов.

1 лайк

Я использую этот метод, и он работает отлично. У меня пока не включен HTTPS, поэтому я не могу высказаться о проблемах с Let’s Encrypt.

Я использую эту конфигурацию уже несколько лет на своих тестовых серверах. Однако после обновления до версии 3.5.0.beta5-dev меня теперь перенаправляет на основной сайт при вводе любого поддомена.

Меня очень радовало, что не приходилось разбираться со всеми нюансами сертификатов. Но теперь я в полной растерянности: есть ли инструменты для отладки происходящего?

1 лайк