This is a guide for moving your Discourse instance from one server to another, including all settings and data. This guide applies to self-hosted Discourse instances using Docker.
Required user level: System Administrator
This procedure involves domain and DNS changes. Ensure you have access to both the source and destination servers.
This guide walks you through the process of migrating your Discourse instance from one server to another, ensuring your data, settings, and configuration are preserved.
Disclaimer added by @pfaffman2025-09-12T05:00:00Z.
These instructions don’t work well now because you’re now using https and let’s encrypt, which require the new server to have DNS pointed to it so that it can request keys. What I recommend is follow the Move a Discourse site to another VPS with rsync (perhaps using --exclude postgres* and then backing up and restoring the database from the command line.) This is slick since if you know how, you can tweak your local DNS to point to the new server so you can test that it works while the rest of the internet still sees the old site.
Summary
You will perform the following key steps in this guide:
Back up your current Discourse instance (source server).
Transfer the backup file to your target Discourse instance (destination server).
Restore the backup on the destination server.
Update DNS settings (if applicable).
Adjusting DNS settings (when required)
If you’re using the same domain for the new server, reduce the TTL (time to live) on your DNS entry in advance. This ensures minimal downtime during propagation of the updated DNS records. If you’ll use a new domain, this step can be skipped.
Logging in and preparing the source server
Log in to your source Discourse instance with an account that has administrator permissions.
Ensure both the source and destination servers are using:
The same Discourse version.
The same set of plugins.
Upgrade the Discourse version on both servers by visiting /admin/upgrade.
Avoid restoring a newer backup onto an older Discourse version, or incompatible PostgreSQL versions, as this may result in errors.
Creating and downloading the backup
Navigate to /admin/backups on your source Discourse instance.
Before proceeding, review your app.yml file to ensure any optional settings, such as CDN configurations, installed plugins, or HTTPS support, are consistent between the source and destination servers.
The restoration process will begin. This may take some time depending on your database size. After the process completes, you’ll be logged out automatically.
Finishing up and logging in
Log into your destination Discourse instance with your admin credentials.
If the site was backed up using HTTPS, ensure HTTPS is enabled on the new server. If not properly configured, use the Rails console to disable the “force https” setting temporarily.
Re-enable any optional configurations by editing the app.yml file and rebuilding your instance. This may include:
Enabling CDN support.
Installing additional plugins.
Setting HTTPS configurations.
Common issues and solutions
Backup file is not restoring
Check that the Discourse and PostgreSQL versions match between the source and destination servers.
Unable to log in after restoration (with HTTPS enabled)
Use the Rails console to disable force https temporarily by running:
Я считаю, что разумно выразить обеспокоенность и спросить, соответствует ли это документации. Недавно я обновил свой форум Discourse и столкнулся с проблемами, которые нарушили работу системы. Я просто обновлялся с одной версии до последней. Речь шла о новых плагинах, которые теперь входят в основную систему Discourse.
Я считаю, что переход на другой экземпляр с более новой операционной системой — это существенное изменение. Если я решу попробовать этот подход, я хотел бы получить как можно больше отзывов.
Буду признателен за любые полезные комментарии. Спасибо.
Это руководство несколько выходит за рамки конкретного изменения.
Основные обновления — это, как правило, шаги, которые нужно выполнять с открытым умом, поскольку они часто сопровождаются устареванием функций и изменениями.
Однако это отличается от миграции, и данное руководство не датировано 11-летней давностью
Кажется, что да, хотя я не смотрел особенно внимательно. Нет. Новый сайт не сможет получить ключи от Let’s Encrypt, если DNS не указывает на него. Поэтому вам нужно будет сделать резервную копию, перенести её, переключить DNS на новый сервер, а затем выполнить восстановление.
Если вы ещё не обновились до Postgres 15 (а возможно, даже и после этого), я рекомендую (и делаю сам) использовать --exclude postgres*, выполнить восстановление, затем сделать резервную копию основного сайта и восстановить её на новом сервере. После этого переключите DNS. В инструкции по rsync предлагается остановить базу данных, чтобы скопировать её файлы напрямую. Однако в некоторых случаях это может работать не очень хорошо, поэтому чаще я делаю резервную копию только базы данных и восстанавливаю её.
РЕДАКТИРОВАНИЕ: Я добавил это в оригинальный пост.
Спасибо, Джей! Я долго не мог понять, почему у меня возникали трудности с URL, DNS и LetsEncrypt в недавнем прошлом при попытке следовать инструкциям из первого сообщения.
В конце концов я справился, создав поддомен для нового сайта, убедившись, что восстановленный сайт на новом сервере работает, а затем быстро переключив DNS и URL. Но всё это было довольно рискованно и болезненно (особенно последующая «беготня» с переназначением ссылок!).
Теперь понятно, зачем мне пришлось делать всё это. И хорошо знать, что rsync позволяет обойти некоторые из этих проблем.
Кажется, что чёткие инструкции здесь очень помогли бы другим, так как сейчас всё немного запутанно — и я не уверен, как лучше поступить в будущем. Не могли бы вы включить своё предупреждение в первое сообщение, переписав его (возможно, @SaraDev)?
Просто добавляю сюда крайний случай миграции, с которым я столкнулся, на случай, если это поможет кому-то ещё.
Я столкнулся с крайним случаем Let’s Encrypt/SSL при переносе автономного экземпляра Discourse на новый VPS, поэтому я записал точные шаги по диагностике и восстановлению, на случай, если они будут полезны кому-то ещё, следующему этому руководству.
В моём случае nginx внутри app не запускался, потому что оба файла .cer в /var/discourse/shared/standalone/ssl/ превратились в файлы нулевого размера:
PEM_read_bio_X509_AUX() failed
Пересборка снова попыталась выпустить сертификат, и после нескольких попыток я уперся в лимит скорости выпуска сертификатов Let’s Encrypt. Копирование всё ещё действительных файлов сертификатов со старого сервера само по себе не помогло, потому что запуск app снова заменял их на файлы нулевого размера.
Что в итоге помогло, так это остановка app и копирование как рабочей директории /var/discourse/shared/standalone/ssl/, так и соответствующего состояния /var/discourse/shared/standalone/letsencrypt/ со старого сервера, а затем повторный запуск контейнера.
Я задокументировал полную последовательность действий здесь:
Это диагностические/восстановительные заметки по данной конкретной миграции, а не замена официальной документации по миграции или HTTPS.
Также существует более старая тема на Meta, описывающая связанную проблему с файлами .cer нулевого размера: