Self-hosting migration example — VPS to VPS

I’m sharing my recent experience of migrating a self-hosted Discourse installation from one VPS to another, as a way of saying ‘thanks!’ to the creators of Discourse and its community of administrators. This migration preserves LetsEncrypt SSL & email configurations.

The original installation was on a Google Cloud Platform (GCP) g1-small instance type (1 vCPU, 1.7 GB RAM), using the official guide ( & tracking the tests-passed branch.

The new installation is on an Evolution Host ‘Developer’ type KVM VPS (2 CPU cores, 2 GB RAM, 40 GB SSD, 7m23s rebuild time, €10/mo). Ubuntu Server 18.04.4 minimal was installed with a 1GB swap partition (likely based on a template).

If your host was installed with extra software, be sure to remove unnecessary software, e.g. web servers, and be sure to secure your host (default usernames, passwords, sshd configs, etc.).

What follows are the terminal commands issued as root, and scrubbed of installation-specific data (replace parts in ALL CAPS with your own). Please comment with any corrections or questions!

New host preparation

apt update && apt -y dist-upgrade
apt install -y byobu mosh htop iotop hugepages curl git && byobu-enable

hugeadm --thp-never

fallocate -l 1G /swapfile
chmod 600 /swapfile
mkswap /swapfile
echo '/swapfile       swap    swap    auto      0       0' | tee -a /etc/fstab
echo 'vm.swappiness = 10' > /etc/sysctl.d/30-discourse-swap.conf

git clone /var/discourse


Old host preparation & backup of Discourse files

cd /var/discourse
./launcher rebuild app

./launcher enter app
discourse backup

(note the filename of your Discourse backup)

cp -v containers/app.yml ~
cd shared/standalone
cp -v settings.yml ~
tar cvf ~/ssl.tar ssl
tar cvf ~/letsencrypt.tar letsencrypt

cd ~
scp -C ssl.tar letsencrypt.tar app.yml settings.yml USERNAME@NEW-HOST-IP:~
scp /var/discourse/shared/standalone/backups/default/YOUR-DISCOURSE-BACKUP.tar.gz USERNAME@NEW-HOST-IP:~

New host restore Discourse

(move the files copied with scp above to the root user’s home directory)

echo 'NEW-HOST-IP YOUR-DISCOURSE-FQHN' | tee -a /etc/hosts

cd /var/discourse
cp -v ~/app.yml containers

mkdir -v shared/standalone
cd shared/standalone
cp -v ~/settings.yml .   
tar xvf ~/ssl.tar
tar xvf ~/letsencrypt.tar

cd /var/discourse

(discourse-setup should complete error-free, allowing you to check all relevant configuration info)

mkdir -v shared/standalone/backups/default
cp -v ~/YOUR-DISCOURSE-BACKUP.tar.gz shared/standalone/backups/default

./launcher enter app
discourse enable_restore
discourse restore YOUR-DISCOURSE-BACKUP.tar.gz
discourse disable_restore

Testing from your local machine

echo 'NEW-HOST-IP YOUR-DISCOURSE-FQHN' | tee -a /etc/hosts

Browse to https://YOUR-DISCOURSE-FQHN/admin/email

At the bottom of the page, enter your email address to test email sending, and browse around your Discourse site to confirm working status.

When you are satisfied that all is is working order, change the DNS A record for YOUR-DISCOURSE-FQHN to point to your new host’s IP address.