As discussed below, a warning for newbies:
- this is an advanced method! there is an automated, web UI way to restore from backups at
/admin/backupswhich is so much easier.
- with the method below, no automatic backup is kept of the
/var/discourse/containers/app.ymlfile which contains essential SMTP credentials and SSL customizations. Keep a copy of this offsite whenever you change it.
- If you are using digital ocean, keep frequent snapshots of your droplets - preferably before each time you run
./launcher rebuild appor do any upgrades. Unfortunately in my case this takes an hour each time and it’s a manual process - but it’s totally worth it if you are not familiar with docker and want to avoid a headache later.
Continuing the discussion from Migrate db from old Discourse to new without updating:
Dropping and recreating the schema is required if the current database contains a table or view that the old one does not, because of referential integrity and pg_dump not adding
CASCADE to its drop statements.
This could be easier if the extensions weren’t stored in the public schema.
Upgrading Discourse is not very hard, but there is always a risk involved. This is why creating a backup is always a strong recommendation before upgrades are installed – but what should you do when your current version is so old that it does not have the backup feature?
The safest way to do this is to not attempt any in-place upgrades on the existing, outdated Discourse instance. Instead, we will manually create a backup and import it into a blank but up-to-date Discourse instance.
The default path for the docker manager scripts has recently changed from
/var/discourse. Since the main purpose of this howto is to help admins of older versions of Discourse to migrate to a new versions, I will use the old default path name throughout the howto.
If you have a newer version of Discourse and the docker manager, simply switch the path names mentioned above where appropriate.
To create the backup, we need access to Discourse’s database and uploaded files. This depends a lot on your current setup. If you
- If your old Discourse…
- lives in a Docker container, enter it:
sudo ./launcher enter app
su - discourse
- does not live in a Docker container, you should at this point ensure that the user you’re logged in as can use
pg_sqlto connect to Discourse’s production database and has access to the uploaded files. You may also have to adjust the directory and file names below.
Export the database and uploaded files:
pg_dump -xOf /shared/discourse-backup.sql -d discourse -n public
gzip -9 /shared/discourse-backup.sql
tar -czf /shared/discourse-uploads.tar.gz -C /var/www/discourse/public uploads
Almost done. Type
exittwice to leave the container, then copy the files
discourse-uploads.tar.gzfrom the host’s shared folder, typicalls
/var/docker/shared/standaloneand store them somewhere safe. The SQL file contains password-equivalent material, so don’t put this file on a webserver and don’t send it unencrypted.
As above, this procedure depends on your particular setup, so this howto can only cover the case that you followed the supported setup instructions and have Discourse running in an up-to-date Docker container.
Upload the backup files and copy them into
/var/docker/shared/standalone, then run:
gzip -d /var/docker/shared/standalone/discourse-backup.sql.gz
As above, enter the container:
sudo ./launcher enter app
Flush your new Discourse’s database. This step is destructive; you must be absolutely certain that you are in the correct container, connecting to the correct database and that it contains no important data.
sudo -u postgres psql discourse <<END DROP SCHEMA public CASCADE; CREATE SCHEMA public; ALTER SCHEMA public OWNER TO discourse; CREATE EXTENSION IF NOT EXISTS hstore; CREATE EXTENSION IF NOT EXISTS pg_trgm; END
Restore the backup data:
su - discourse
rm -rf /var/www/discourse/public/uploads
tar -C /var/www/discourse/public -xzf /shared/discourse-uploads.tar.gz
psql -d discourse -f /shared/discourse-backup.sql
Bring the old database up-to-date by migrating it:
RAILS_ENV=production bundle exec rake db:migrate
Exit and restart the container:
sudo ./launcher restart app