Migrate an old Discourse install to Docker

Deploying Discourse on Docker is currently our recommended setup. It avoids many pitfalls installations have, such as misconfigured nginx, sub-optimal Ruby defaults and so on.

The Docker based setup ensures we are all on the same page when diagnosing installation issues and completely eradicates a class of support calls.

Today, all sites hosted by Discourse are on Docker.

This is a basic guide on how to move your current Discourse setup to a Docker based setup.

Getting started

First, get a blank site with working email installed. Follow the guide at GitHub - discourse/discourse_docker: A Docker image for Discourse and install a new, empty Discourse instance.


  • Bind the web to a different port than port 80, if you are on the same box. Eg:

        - "81:80"
  • Be sure to enter your email in the developer email section, so you get admin:

        # your email here
        DISCOURSE_DEVELOPER_EMAILS: 'my_email@email.com'
  • Make sure email is setup and working by visiting /admin/email and sending a test email.

  • Make sure you have can enter your container ./launcher enter my_container must work.

If any of the above is skipped your migration will fail.

At the end of this process you will have a working website. Carry on.

Exporting and importing the old site

  • Ensure you are running the absolute latest version of Discourse. We had bugs in the export code in the past, make sure you are on latest before attempting an export.

  • On your current instance

    • go to /admin/backups and click on the button.
    • once the backup is done, you will be able to it.
  • On your newly installed docker instance

    • enable the allow_restore site setting
    • refresh your browser for the change to be taken into account
    • go to /admin/backups and your backup.
    • once your upload is done, click on the button
  • Change port binding so its on 80

  • Rebuild container ./launcher rebuild app

Yay. You are done.


For some reason, I was about to start a topic for this exact same purpose. And then you made this public. How did you read my mind? :stuck_out_tongue:

Here’s an imgur album with screenshots of the Export/Import process, in case anybody’s a more visual learner: http://imgur.com/a/SuVtd

Also, once you have done a successful restore (which is what you do in this guide), the button in the Backups tab will be enabled. You’ll have to re-enable allow_restore to use it.


/admin/backups is available starting in which version?
I want to to migrate to an empty Docker based instance from a instance.
If this possible?
One more question, is CentOS out of the question for running Discourse under Dockers?

The first step, per the above instructions, is to update to the latest version of Discourse.

Done! The upgrade wasn’t so bad after all (pretty straight forward).
Now running on bleeding edge!
@codinghorror How did it go the meeting in Madrid, still in town?

I have a problem with the schema dumping from your backup script. pg_dump works for user discourse from the command line but not from your script:

[2014-02-28 05:18:57] sh: pg_dump: command not found
[2014-02-28 05:18:57] EXCEPTION: pg_dump failed

Is it a cron job?

Interesting, @zogstrip will have a look

I have uploaded my backup but it still says ‘No backup available.’

EDIT: An older backup worked.

Should I not enable read-only mode before running the initial backup to avoid users posting during the upgrade?

Backups automatically enable read-only mode when they begin.


OK, but what if my users post after the backup is completed? Only the backup will be moved to the new install.

Are you saying that read-only mode is left on after a backup is completed and would need to be manually turned off to allow users to post? Or would read-only mode be disabled automatically when the backup is complete?

Yeah, this is what happens. You can click the button to reenable read-only, though, and there probably won’t be a post submitted in the meantime :wink:

Without labouring the point too much, if I want to move my data to a new install, I would want to enable read-only mode first, then takes a backup and move the data to a new install. At no point would I want users to have access to writing data to the original copy of the data.

So, with this in mind, if read-only mode is enabled prior to taking a backup, will it be automatically disabled once the backup is completed? If so, this is a bug IMO.

Backup/restore operations used to always enable read-only mode when they start and disable it when they finish.

Agreed and fixed :wink:



Tip: Be sure to disable the old services before rebooting…

update-rc.d -f nginx disable
update-rc.d -f postgresql disable
update-rc.d -f redis-server disable

(Once we get systemd in 15.04, that’ll be systemctl nginx.service disable I think ;))

I’m responsible for discourse over at http://thepeople.p2pu.org. We are running version in a pre-pre-docker environment.

I tried setting up a new discourse instance with docker, grab the database from the old installation, load it into the docker db and then rebuild the docker image to rerun the migrations on the old database. Unfortunately that crashed and burned. So much wasted caffeine.

Now, I may have done something wrong in that process. In fact, I’m hoping I did something wrong. Are there other important places where data also lives? Redis? Should I manually run the migrations? Would the migrations work from any old version of the database or am I just being optimistic?

I guess this would be my last resort. And it would probably be more like: recreate the old environment, update to latest, fix what breaks, export.

Any suggestions, or do I need to print myself a teashirt saying: “they told me it was pre-alpha, but it looked cool and worked…”, suck it up and do the dreaded update of the old environment?

Yes! You need to an incomplete upgrade, and run the migrations before taking the backup. (Incomplete, as in, don’t bother precompiling assets because you’re not going to start the web server.) Use script/discourse backup to take the backup, then download it using SCP.

I actually just did this for @cyanbane - https://meta.discourse.org/t/looking-for-help-updating-an-instance-of-0-8-2/15577

1 Like

I have allow restore set in settings:

However the restore button won’t allow me to click it:

Anything else I need to set?

reload the page :slight_smile:

sorry, we got to fix this some time @zogstrip


Works, thank you :slight_smile:

Aside: Odd that something that we are used to trying on web pages we forget to try on web apps.