# Manually create and restore Discourse backups

**URL:** https://meta.discourse.org/t/manually-create-and-restore-discourse-backups/18273
**Category:** Sysadmins
**Tags:** how-to
**Created:** [July 30, 2014, 2:10pm UTC](https://meta.discourse.org/t/manually-create-and-restore-discourse-backups/18273 "2014-07-30T14:10:02Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![elberet](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/elberet/32/122404_2.png) [@elberet](https://meta.discourse.org/u/elberet)
#### Post date: [July 30, 2014, 2:10pm UTC](https://meta.discourse.org/t/manually-create-and-restore-discourse-backups/18273/1 "2014-07-30T14:10:02Z")

</div>

As discussed [below](https://meta.discourse.org/t/advanced-manual-method-of-manually-creating-and-restoring-discourse-backups/18273/7), a warning for newbies:

1. this is an advanced method! there is an automated, web UI way to restore from backups at `/admin/backups` which is so much easier.
2. with the method below, no automatic backup is kept of the `/var/discourse/containers/app.yml` file which contains essential SMTP credentials and SSL customizations. Keep a copy of this offsite whenever you change it.
3. If you are using digital ocean, keep frequent snapshots of your droplets - preferably before each time you run `./launcher rebuild app` or 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](https://meta.discourse.org/t/migrate-db-from-old-discourse-to-new-without-updating/17956/6):

> [@sam](#):
>
> I like this, can you perhaps may a canonical howto here cc @techAPJ

* * *

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.

#### Note regarding default path changes

The default path for the docker manager scripts has recently changed from `/var/docker` to `/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.

## Creating the backup

To create the backup, we need access to Discourse’s database and uploaded files. This depends a lot on your current setup. If you

1. If your old Discourse…

- lives in a Docker container, enter it:  
`cd /var/docker`  
`git pull`  
`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_sql` to 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.

1. 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`

2. Almost done. Type `exit` twice to leave the container, then copy the files `discourse-backup.sql.gz` and `discourse-uploads.tar.gz` from the host’s shared folder, typicalls `/var/docker/shared/standalone` and 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.

## Restoring the backup

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.

1. Upload the backup files and copy them into `/var/docker/shared/standalone`, then run:  
`gzip -d /var/docker/shared/standalone/discourse-backup.sql.gz`

2. As above, enter the container:  
`cd /var/docker`  
`sudo ./launcher enter app`

3. 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.

```plaintext
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

```

1. 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`

2. Bring the old database up-to-date by migrating it:  
`cd /var/www/discourse`  
`RAILS_ENV=production bundle exec rake db:migrate`

3. Exit and restart the container:  
`exit`  
`exit`  
`sudo ./launcher restart app`

---

<div class="post-metadata">

### Author: ![zda](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/zda/32/108514_2.png) [@zda](https://meta.discourse.org/u/zda)
#### Post date: [August 20, 2014, 12:09am UTC](https://meta.discourse.org/t/manually-create-and-restore-discourse-backups/18273/5 "2014-08-20T00:09:51Z")

</div>

Note if you’re migrating away from Heroku, you can’t use pg\_dump on the server directly, so you’ll probably want to pg:pull your database to your local machine, and then follow the above directions from step 2.

You also will probably skip the commands related to uploaded files, since Heroku probably already forced you to use S3 for assets.

(Also, if for any reason you’re using pgbackup restore, be sure to pg:reset first or you might end up with a frankenschema like I did and your migrations won’t run.)

---

<div class="post-metadata">

### Author: ![tobiaseigen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tobiaseigen/32/539204_2.png) [@tobiaseigen](https://meta.discourse.org/u/tobiaseigen)
#### Post date: [February 17, 2015, 9:30pm UTC](https://meta.discourse.org/t/manually-create-and-restore-discourse-backups/18273/7 "2015-02-17T21:30:39Z")

</div>

(whoa, just found this old draft from months ago which apparently I never saved. Still relevant and hopefully useful to others who come after me)

I have some suggestions for improving this topic, having just wrangled (with success!) with restoring backups as a newbie.

1. suggest adding text right at the top explaining that there is an automated, web UI way to restore from backups and link to a topic explaining backup and restore for beginners - I was not aware of this option until after attempting the manual process which is not for the faint of heart. I would even change the title of this howto to add “Advanced” or to specify that the topic is specifically for people with very old discourse sites.
2. no automatic backup is kept of the `/var/discourse/containers/app.yml` file 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 app` or 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. 🙂

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [February 17, 2015, 9:40pm UTC](https://meta.discourse.org/t/manually-create-and-restore-discourse-backups/18273/8 "2015-02-17T21:40:36Z")

</div>

It is wiki now, feel free to improve the howto.

---

<div class="post-metadata">

### Author: ![ernsheong](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ernsheong/32/108797_2.png) [@ernsheong](https://meta.discourse.org/u/ernsheong)
#### Post date: [February 26, 2015, 8:53am UTC](https://meta.discourse.org/t/manually-create-and-restore-discourse-backups/18273/9 "2015-02-26T08:53:14Z")

</div>

I am trying to restore from an earlier auto generated backup to S3.

The `RAILS_ENV=production bundle exec rake db:migrate` step seems to be overriding all the data even after I have restored the data with `psql -d discourse -f /shared/discourse-backup.sql`. I end up with a clean install in the end.

Probably of note: I have two containers, web and data.

What am I missing?

---

<div class="post-metadata">

### Author: ![zogstrip](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/zogstrip/32/512781_2.png) [@zogstrip](https://meta.discourse.org/u/zogstrip)
#### Post date: [February 26, 2015, 8:55am UTC](https://meta.discourse.org/t/manually-create-and-restore-discourse-backups/18273/10 "2015-02-26T08:55:40Z")

</div>

Why aren’t you restoring the backup via the admin UI?

---

<div class="post-metadata">

### Author: ![riking](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/riking/32/170938_2.png) [@riking](https://meta.discourse.org/u/riking)
#### Post date: [February 26, 2015, 8:57am UTC](https://meta.discourse.org/t/manually-create-and-restore-discourse-backups/18273/11 "2015-02-26T08:57:03Z")

</div>

Yep, @ernsheong restore through the admin UI then `./launcher restart` both containers.

---

<div class="post-metadata">

### Author: ![ernsheong](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ernsheong/32/108797_2.png) [@ernsheong](https://meta.discourse.org/u/ernsheong)
#### Post date: [February 26, 2015, 9:45am UTC](https://meta.discourse.org/t/manually-create-and-restore-discourse-backups/18273/12 "2015-02-26T09:45:41Z")

</div>

Wow, I love you guys! @riking @zogstrip 👍

---

<div class="post-metadata">

### Author: ![vulkanino](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/vulkanino/32/119654_2.png) [@vulkanino](https://meta.discourse.org/u/vulkanino)
#### Post date: [January 19, 2017, 9:41am UTC](https://meta.discourse.org/t/manually-create-and-restore-discourse-backups/18273/15 "2017-01-19T09:41:58Z")

</div>

> [@elberet](#):
>
> pg\_dump -xOf /shared/discourse-backup.sql -d discourse -n public

permission denied (on the /shared folder).

---

<div class="post-metadata">

### Author: ![benjaoming](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/benjaoming/32/161986_2.png) [@benjaoming](https://meta.discourse.org/u/benjaoming)
#### Post date: [November 22, 2019, 4:07pm UTC](https://meta.discourse.org/t/manually-create-and-restore-discourse-backups/18273/16 "2019-11-22T16:07:25Z")

</div>

Not sure that I have permissions to edit the wiki post above. Is it a pilot error from my side?

Anyways, commands need to be adapted to `/shared/` structure. For instance:

```
 tar -C /var/www/discourse/public -xzf /shared/discourse-uploads.tar.gz

```

Should be:

```
tar -cvzf /shared/discourse-uploads.tar.gz -C /shared uploads

```

And it’s a bit critical as the current backup command will silently create an empty backup uploads.tar.gz, as it doesn’t follow the symlink to a different mount.

---

<div class="post-metadata">

### Author: ![Kuro22](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kuro22/32/261055_2.png) [@Kuro22](https://meta.discourse.org/u/Kuro22)
#### Post date: [June 16, 2022, 3:16pm UTC](https://meta.discourse.org/t/manually-create-and-restore-discourse-backups/18273/17 "2022-06-16T15:16:55Z")

</div>

> [@elberet](#):
>
> - lives in a Docker container, enter it:  
> `cd /var/docker`  
> `git pull`  
> `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_sql` to 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.
> 
> 1. 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`

Sorry to bump this topic up. 😢 This howto seems to be out of date and needs an update.

My instance has run into some issues, I have no longer access to it from the browser. So I’m trying to find a way to get a backup of my site manually and then I found this topic.

Any help would be appreciated!

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [June 16, 2022, 3:32pm UTC](https://meta.discourse.org/t/manually-create-and-restore-discourse-backups/18273/18 "2022-06-16T15:32:47Z")

</div>

Have you tried

```plaintext
cd /var/discourse
./launcher rebuild app

```

I don’t see anyhing about what you quoted that it out of date. Is this a [standard install](https://meta.discourse.org/t/142537?silent=true)? Do you see anything in `/var/discourse/containers`?

---

<div class="post-metadata">

### Author: ![Kuro22](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kuro22/32/261055_2.png) [@Kuro22](https://meta.discourse.org/u/Kuro22)
#### Post date: [June 16, 2022, 3:52pm UTC](https://meta.discourse.org/t/manually-create-and-restore-discourse-backups/18273/19 "2022-06-16T15:52:22Z")

</div>

Thanks for your quick response!

Yes, I have tried rebuilding many times but keep getting fails… So I created a new droplet and installed a fresh Discourse instance on it, with success. And I have restored a backup which is created a month ago, what I’m trying to do is get back the data of these days.

> [@pfaffman](#):
>
> anything in `/var/discourse/containers`?

Yes, there are app.yml and one backup for it.

> [@pfaffman](#):
>
> I don’t see anyhing about what you quoted that it out of date.

The `/var/docker` directory doesn’t exist, so I `cd /var/discourse` and followed the guide, until I got prompted

```plaintext
pg_dump: error: connection to database "discourse" failed: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: role "root" does not exist

```

after executing `pg_dump -xOf /shared/discourse-backup.sql -d discourse -n public`.

I’m a newbie, sorry for the disturbing if this guide is actually not outdated.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [June 16, 2022, 4:10pm UTC](https://meta.discourse.org/t/manually-create-and-restore-discourse-backups/18273/20 "2022-06-16T16:10:07Z")

</div>

did you

```
  su - postgres

```

before trying the `pg_dump`?

But you probably want to figure out why you can’t rebuild, as the issue might be something that will keep your database from restoring
