Download and restore of site settings

(Jay Pfaffman) #1

For sites interested in moving to Discourse from another forum or trying out Discourse before an import, it’s tedious to see that settings get moved from a test site to the live one, or that settings done on a live instance can be easily moved to a restore from an import that started with a clean slate.

Now that themes are supported, part of this problem is solved, but it’s still tedious to copy potentially dozens of settings from one site to another.

I started looking at a clean (yet naive) way to do this and started by looking at what data explorer returns for select * from site_settings. That was a good start, but if I reset a value via the web interface, the value still shows up in data explorer. Is it different in rails?

Edit: Another example of my being crazy or looking at the wrong tab. I see now that the setting I changed is still there (of course) but is now blank (as I’d expect). I’d still welcome input on how to best go about this. A plugin that spits out JSON and sucks in an upload?

Any hints on how to go about this?


(Jay Pfaffman) #3

Now you can, if you can run a ruby script.

To create/retrieve settings

Create a JSON settings dump by visiting and saving the file somewhere convenient.

Retrieve your site’s API key from

To install these settings to another site

Do this:

./discourse-settings-uploader HOSTNAME API_KEY API_USER SETTINGS_FILE

For example:

./discourse-settings-uploader d35989078a system site_settings.json


This script does minimal error checking and could destroy your site, cause fires, or hurt people.

You should make a backup of your site before you use this script.


(Sam Saffron) #4

We should pull this into a rake task, cause I want core to ship with it.


(Jay Pfaffman) #5

I’d be flattered.

Would it restore the settings to the local instance, or, as my script does, push them to a remote instance via the API?

On a related note, a rake task to call create_master_key to make it easier to get the API key from a script would be useful.

I’ve tried

echo "ApiKey.create_master_key" | docker exec -w /var/www/discourse -i app bundle exec rails c

but it fails with FATAL: Peer authentication failed for user "discourse" (PG::ConnectionBad).


(Sam Saffron) #6

I would just use straight json here:

rake site_settings:export > settings.yml
rake site_settings:import < settings.yml

or something like that.

@blake is also interested so I think he can probably help.


(Blake Erickson) #7

A rake task for this now exists!

Here is an example of an import. It checks for bad settings (NOT FOUND), should show any errors (setting a username that doesn’t exist), and show you which settings changed, and will only update a value if the new setting is different from the current value.

$ rake site_settings:import < ~/tmp/settings.yml

starting import...

NOT FOUND: existing site setting not found for blake_key
Changed title FROM: Discourse TO: Blake's Site
Changed site_description FROM:  TO: Blake's test site
ERROR: site_contact_username: There's no user with that username.
Changed invite_only FROM: f TO: true
Changed login_required FROM: f TO: true

 Updated:   4
 Not Found: 1
 Errors:    1

Afterwards you can also check the Staff Action logs to verify the changes.

@pfaffman I do still really like your api version, and I would be the perfect tool to add to the discourse CLI app that I started working on a couple of years go that I haven’t had time for but would still like to exist.


Restore a backup from command line
(Jay Pfaffman) #8

Cool. Can’t wait to use it.

Will it work on a file downloaded from /admin/site_settings.json?

Ah. That could be useful! I have a handful of such stuff that will be part of my lc-panel that installs and manages discourse installations. Maybe soon I’ll get it up. . .


(Blake Erickson) #9

Nope, you will need to log into the box and run a site_setting:export > settings.yml

and it will look like this:

blake_key: awesome
default_locale: en
title: Blake's Site
site_description: Blake's test site
contact_email: ''
contact_url: ''
site_contact_username: 'blake'

I decided to go with a single line and just do key/value for each setting, rather than including all the other info like last updated, created date, type, etc because I don’t think we really need those right now.

Anyways you could probably write a simple ruby script that parses your json file to the same format as this yaml file.

Also if there was a way to make all site settings read only from the UI, I think this would lead to a cool feature where all site settings could be controlled via git, and if someone wanted to make a change they would have to make a pr. Or a script could be run everyday setting the site’s setting back in case there were any changes. But these are probably all imaginary problems no one actually has.



In the admin settings on the website there’s a setting to “only show overridden”, it would be great if there was a similar option to export only the changed settings to a file!

In the meantime I guess I can export a copy of the settings from a blank test deployment and do a simple diff on the exported files.

I’m trying to document how our internal forum is set up and since there’s over 600 settings I’m going to have to trim the list a bit in the docs :wink:


(Sam Saffron) #11

Very reasonable feedback!

I changed it so the rake task only exports settings that deviated from default.