Как мигрировать Discourse с одного сервера на другой с тем же DNS-именем

Я пытаюсь перенести Discourse с личного хостинга на сервер Amazon LightSail. Я изучил форум и прочитал все темы о миграции серверов и настройке Discourse:

Move your Discourse Instance to a Different Server
Restore a backup from the command line
How To Install Discourse on Ubuntu 18.04 | DigitalOcean
discourse/docs/INSTALL-cloud.md at main · discourse/discourse · GitHub

Как я понимаю, процесс выглядит так:

  1. Установка нового сервера Discourse
  2. Экспорт резервной копии с существующего сервера (в настоящее время резервное копирование настроено на сохранение в S3, но, насколько я понимаю, в данном случае потребуется ручное создание файла резервной копии)
  3. Импорт резервной копии на новый сервер Discourse (вручную, так как, насколько я понимаю, он не сможет загрузить её напрямую из S3)

Я немного застрял на этапе выполнения шага 1 из-за нескольких ограничений: у меня есть одно доменное имя, и я хочу использовать то же доменное имя для нового сервера. При этом я не хочу простоя (моя цель — завершить настройку нового сервера, восстановить резервную копию и только после этого изменить запись DNS, указав её на новый сервер, чтобы избежать простоя, так как оба сервера будут работать одновременно).

Как я понимаю, при настройке нового сервера Discourse я могу скопировать файл app.yml с существующего сервера на новый, а затем запустить discourse-setup. Проблема, которую я вижу здесь, заключается в том, что при этом будет использоваться то же доменное имя, что и на существующем сервере (что мне и нужно), но я предвижу две проблемы, с которыми пытаюсь разобраться:

  1. Let’s Encrypt не сможет выдать SSL-сертификат для нового сервера, так как доменное имя всё ещё указывает на старый сервер.
  2. Без SSL-сертификата (конфигурация старого сервера настроена на использование только SSL, что будет перенесено в app.yml) сервер не запустится.
  3. Я пробовал подключаться к серверу Discourse с помощью перенаправления DNS, но если введённый URL не совпадает с конфигурацией в app.yml, либо NGINX, либо сам Discourse не будут работать, и в браузере возникнет ошибка при попытке подключения. Таким образом, без веб-интерфейса я не могу запустить процесс восстановления.

Итак, как мне завершить настройку нового сервера Discourse, используя файл app.yml с существующего сервера, а затем восстановить резервную копию и выполнить переключение DNS? Или есть более простой способ сделать это?

Если вы не будете использовать тот же бакет S3, то существует скрытая настройка, которая принудительно загружает файлы S3 для резервного копирования. Вы можете найти её имя в файле настроек и установить через консоль Rails. Есть тема, посвящённая этому вопросу, но, возможно, проще всего посмотреть в settings.yml.

Вам не нужно запускать discourse-setup, достаточно скопировать app.yml и пересобрать контейнер.

Вы можете синхронизировать сертификаты Let’s Encrypt с помощью rsync. Более того, можно скопировать весь каталог /var/discourse (возможно, исключив некоторые логи и тому подобное).

В идеале цель — «поднять и перенести» (lift n shift), но с Amazon Lightsail это невозможно, так как нельзя импортировать существующий образ. Так что да, будет использоваться тот же самый S3.

Кажется, ваш подход ближе всего к «поднять и перенести». Если я правильно понимаю, что вы имеете в виду, я могу просто упаковать в tar/gz всю папку /var/discourse с исходного сервера, распаковать её на новый сервер, затем выполнить discourse start и просто перенаправить DNS на новый сервер. Всё? Нужно ли пересобирать Discourse на новом сервере? А что насчёт Nginx, Docker и других зависимостей вне этой папки?

Да, перемещайте файлы так, как вам удобнее. Да, вам потребуется выполнить пересборку для создания и запуска нового контейнера.

Спасибо. Оказывается, миграция «lift n shift» была не такой чистой, как я думал: перед и после неё необходимо выполнить несколько проверок, чтобы обеспечить плавный переход (Postgres был обновлён с версии 12.0 до 13.0, что научило меня нескольким урокам в процессе миграции «lift n shift»). Ниже приведено пошаговое руководство для будущих ссылок для тех, кто хочет перенести данные на сервер Amazon LightSail (1 ГБ ОЗУ):

Исходный сервер

  • Создайте резервную копию в S3
  • cd /var/discourse
  • ./launcher rebuild # получите последнюю сборку для лёгкого перехода
  • ./launcher cleanup # очистите систему, чтобы удалить старые данные и уменьшить размер пакета
  • ./launcher stop app # если этого не сделать, при попытке пересборки позже с Postgres возникнет ошибка
  • tar -zcvf /var/discourse discourse.tar.gz

Новый сервер Amazon LightSail

  • Установите образ Ubuntu 20.20 от Amazon (1 ГБ ОЗУ)
  • Установите Docker
  • Создайте файл подкачки 2 ГБ # если этого не сделать, пересборка может завершиться ошибкой
  • Настройте vm.overcommit_memory=1 # если этого не сделать, при пересборке с Postgres может возникнуть ошибка
  • Через FTPS/transfer скопируйте discourse.tar.gz с исходного сервера
  • tar -zxvf discourse.tar.gz -C /
  • cd /var/discourse
  • Установите UNICORN_WORKERS в app.yml равным 2 # увеличение этого значения выше 2 при 1 ГБ ОЗУ может привести к использованию файла подкачки и замедлению работы из-за чрезмерной активности диска
  • ./launcher rebuild
  • Измените DNS, чтобы он указывал на новый сервер Amazon

Существует ли более простой способ миграции серверов (lift n shift) без необходимости проходить весь процесс настройки Discourse?

Вы имеете в виду, что не нужно запускать discourse-setup, или вы имеете в виду, что не нужно собирать контейнер, необходимый для работы Discourse? Если вы имеете в виду последнее, то это возможно, если загрузить старый образ в репозиторий, который сможет использовать новый сервер, но это не то, с чем новичок легко справится.

Ваш процесс был усложнен обновлением до PG13. Возможно, было бы немного проще собрать новый образ с нуля на новом сервере и восстановить резервную копию со старого, но у вас всё равно возникнут некоторые сложности с получением сертификатов Let’s Encrypt на новом сервере.

Да, именно это мешало мне выполнить ./discourse-setup на новом сервере, а затем восстановить систему из образа S3 (и как это сделать без доступа к веб-консоли администратора, поскольку DNS всё ещё указывал на старый сервер, и, насколько мне известно, Discourse не отвечает на IP-адрес в браузере). Поскольку у меня была рабочая система и мне нужно было переключить DNS с старого на новый сервер в реальном времени, отсутствие сертификатов Let’s Encrypt было единственным препятствием.
Если есть способ перенести сертификаты со старой системы на новую, завершить ./discourse-setup без ошибок Let’s Encrypt и восстановить систему из резервной копии S3 без использования веб-консоли, то это был бы более простой вариант.

Если вы скопируете файлы yml из папки containers, то discourse-setup не потребуется (он может скорректировать параметры памяти, если они отличаются на новом сервере, но вы можете сделать это и позже). Вам достаточно выполнить ./launcher rebuild app.

Хорошо, я думаю, я понял, что вы имеете в виду, но для уверенности позвольте мне переформулировать своё понимание.

На исходном сервере была настроена резервная копия Discourse в S3 (это настройки и содержимое сайта).

При копировании файлов yml из containers вся конфигурация исходного сервера переносится на новый сервер. Теперь на новом сервере мне больше не нужно выполнять discourse-setup; вместо этого команда ./launcher rebuild app использует конфигурацию исходного сервера для загрузки последнего образа и настройки Discourse.

Теперь осталось решить два вопроса:

  1. Как передать сертификаты Let’s Encrypt (поскольку DNS всё ещё указывает на исходный сервер, их нельзя создать заново, и, полагаю, это нужно сделать до выполнения ./launcher rebuild app)?
  2. Как восстановить Discourse (настройки + содержимое) из резервной копии S3 после пересборки? Поскольку DNS всё ещё указывает на исходный сервер, есть ли способ получить доступ к веб-интерфейсу администратора Discourse через IP-адрес или localhost, или же резервную копию S3 можно восстановить через консоль?

Если вы скопируете старую директорию /var/discourse, вы получите сертификаты, и пересборка пройдет как ожидалось.

Вы можете восстановить данные из командной строки внутри контейнера.

Спасибо за подробные инструкции. Мне пришлось сделать нечто подобное при переезде на нового хостинга.
Поскольку сайт работал, я не хотел возиться с резервными копиями, поэтому последовал инструкциям здесь.

Почти всё сработало, но восстановление на новом хосте не удалось.
Оказалось, что сопоставление UID/GID на двух хостах не было полностью идентичным, поэтому при запуске Postgres возникала ошибка из-за неверных прав владения папкой с данными.

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

Для сценария, описанного в этом посте, есть одна дополнительная деталь: контейнер ещё не собран, поэтому команда ./launcher enter app на этом этапе не работает. Поскольку процесс восстановления занял бы довольно много времени, я смог использовать docker ps, чтобы получить имя контейнера, выполняющего сборку, а затем зайти в него:

docker exec -it <container_name> bash
chown -R postgres:postgres /shared/postgres_*

Затем восстановление завершается с ошибкой (или вы не можете прервать его с помощью CTRL+C). После остановки просто запустите его снова, и права будут исправлены:

./launcher rebuild app

И всё снова работает :sweat_smile:.

Для всех, кто использует 1 ГБ ОЗУ, обязательно создайте файл подкачки размером не менее 4 ГБ, иначе пересборка не завершится успешно. См. 3.1.x to 3.2.0 upgrade hangs/fails on 1GB instance