# Move from standalone container to separate web and data containers

**URL:** https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413
**Category:** Sysadmins
**Tags:** docker, how-to, advanced-setup, two-container
**Created:** [May 29, 2015, 2:12pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413 "2015-05-29T14:12:22Z")
**Posts on this page:** 20
**Page:** 6

<div class="post-metadata">

### Author: ![RichardNooooh](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/richardnooooh/32/511419_2.png) [@RichardNooooh](https://meta.discourse.org/u/RichardNooooh)
#### Post date: [August 9, 2025, 3:39pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/110 "2025-08-09T15:39:01Z")

</div>

I assume it’s not _strictly_ necessary to download it. Most people are running a single cloud instance, who may or may not have a backup S3 bucket. Downloading the backup would be the only way for this group to make an off-site backup, like you mentioned.

I would even go as far as to make an additional backup system on a completely different provider as well, especially after what recently happened to [this open source dev](https://www.seuros.com/blog/aws-deleted-my-10-year-account-without-warning). Regardless of its validity, it’s a great warning to have a weekly or monthly backup to an entirely separate storage location/provider.

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [September 6, 2025, 6:44pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/111 "2025-09-06T18:44:18Z")

</div>

> [@5minpause](#):
>
> ` ./discourse-setup --two-container`

Thanks @pfaffman for adding this, really painless now! (except for restoring a large backup which is always a little bit of a tense and long wait whatever the setup).

> [@5minpause](#):
>
> `/var/discourse/shared/web_only/backups/default`

btw I think this path is incorrect: should be `web-only` (by default) I think?:

```plaintext
volumes:
  - volume:
      host: /var/discourse/shared/web-only
      guest: /shared
  - volume:
      host: /var/discourse/shared/web-only/log/var-log
      guest: /var/log

```

**PS I’ve edited the OP accordingly**

---

<div class="post-metadata">

### Author: ![Jagster](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jagster/32/192154_2.png) [@Jagster](https://meta.discourse.org/u/Jagster)
#### Post date: [September 6, 2025, 6:50pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/112 "2025-09-06T18:50:18Z")

</div>

> [@5minpause](#):
>
> var/discourse/shared/web\_only/backups/default

Yeah. `web-only` and that is a bit confusing when in every other context it is `web_only`. But perhaps when something is a directory or a container-what-ever is different thing.

What the I know… I just wasted 4 hours fighting with SearXNG and that should be 5 mins jobs (I really dislike docker things)

**edit and off topic**

Really 😳 he and ck is a banned word? It was teached to us in school as a non-offended word. So, they were wrong, obvious 😂

---

<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: [September 6, 2025, 7:01pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/113 "2025-09-06T19:01:34Z")

</div>

> [@Jagster](#):
>
> Really 😳 he and ck is a banned word?

I think that might have been added when watched words were first being tested and just never got removed.

> [@Jagster](#):
>
> Yeah. `web-only` and that is a bit confusing when in every other context it is `web_only`. But perhaps when something is a directory or a container-what-ever is different thing.

Yeah. I get confused about that often. In fact, I think that’s probably why once when I tried to just rename things to switch from single to double-container I got the underscore/dash thing wrong and it failed.

And worse, I am pretty sure it’s my fault. I got some error when I created the two-container option in discourse-setup (maybe containers couldn’t have underscores?) Ruby likes underscores in filenames, so maybe that’s why I used an underscore there? I think that’s it–and I think web\_only can’t work as a docker container name since they also need to be valid hostnames.

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [September 6, 2025, 7:10pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/114 "2025-09-06T19:10:36Z")

</div>

I prefer hyphens in directory paths, so all good as it is, and underscore in the container name honestly, makes sense, so leave it as it is.

btw, I think there should be a _title_ or a self-certified badge on meta for those rocking the two container setup 😉 Once you’ve been here for a year, I think it should be mandatory for your standard installs to be migrated. 🚀

---

<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: [September 6, 2025, 7:32pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/115 "2025-09-06T19:32:03Z")

</div>

> [@merefield](#):
>
> Once you’ve been here for a year, I think it should be mandatory for your standard installs to be migrated.

If not for so much existing documentation about the single-container setup, I’d almost argue that it should be the default, though there’d need to be some tooling to let people know that the database might need attention, or something.

I often see lots of people unhappy about and otherwise scared of two-container installs. (Recently someone wanted the two-container install I’d create when I did their install moved to a single container, for example.) It’s so very rare that it’s a problem, and the one time that it causes problems, it actually saves some hassle since it makes it easy to put off a Postgres Upgrade until you’re ready to do it. You can usually put off a PG upgrade for a good while (except when the AI plugin got added to core and required that extension).

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [September 9, 2025, 1:03pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/116 "2025-09-09T13:03:04Z")

</div>

my backups started failing after this:

```plaintext
[2025-09-09 09:34:50] Creating archive: blah-forum-2025-09-09-093246-v20250828181952.tar.gz
[2025-09-09 09:34:50] Making sure archive does not already exist...
[2025-09-09 09:34:50] Creating empty archive...
[2025-09-09 09:34:50] EXCEPTION: tar --create --file /var/www/discourse/public/backups/default/blah-forum-2025-09-09-093246-v20250828181952.tar --files-from /dev/null
tar: /var/www/discourse/public/backups/default/blah-forum-2025-09-09-093246-v20250828181952.tar: Cannot open: Permission denied
tar: Error is not recoverable: exiting now

```

looking at permissions from within the `web_only` container:

```plaintext
/var/www/discourse/public/backups# ls -l
total 4
drwxr-xr-x 2 root root 4096 Sep 6 12:37 default

```

if I look at another instance ([standard install](https://meta.discourse.org/t/142537?silent=true)), the ownership is different:

```plaintext
/var/www/discourse/public/backups# ls -l
total 4
drwxr-xr-x 2 discourse www-data 4096 Sep 9 03:46 default

```

what’s gone wrong here and what should I change on that directory for the web\_only container - should it be the same as for [standard install](https://meta.discourse.org/t/142537?silent=true)?

---

<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: [September 9, 2025, 3:55pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/117 "2025-09-09T15:55:37Z")

</div>

> [@merefield](#):
>
> what’s gone wrong here and what should I change on that directory for the web\_only container - should it be the same as for [standard install](https://meta.discourse.org/t/142537?silent=true)?

tl;dr maybe try

```plaintext
docker exec -it web_only bash
chown -R discourse:www-data /shared/backups

```

And more words.

Without looking, I’d next try rebuilding the data container, hoping that whatever change was made also got made to (or affects) the data container.

The bad-advice answer is to make `...backups/default` world writable and seeing the ownership of the backup.

> [@merefield](#):
>
> ```plaintext
> drwxr-xr-x 2 root root 4096 Sep 6 12:37 default
> 
> ```

> [@merefield](#):
>
> ```plaintext
> drwxr-xr-x 2 discourse www-data 4096 Sep 9 03:46 default
> 
> ```

So I think what you want to do is chown default to discourse.www-data in the web container (that’s the one doing the backups).

Here’s a recent single-container:

```plaintext
root@forum.mbse-capella.org(app):~$ docker exec -it app bash
root@new-app:/# grep www /etc/passwd
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
root@new-app:/# grep discourse /etc/passwd
discourse:x:1000:1000::/home/discourse:/bin/bash

```

At some points in the past the build process would `chown` all the files, but it can take a really long time, so I think that may have been removed at some point (this is more than a feeling than anything based on paying attention to commits).

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [September 9, 2025, 9:49pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/118 "2025-09-09T21:49:07Z")

</div>

> [@pfaffman](#):
>
> `docker exec -it web_only bash`

this is equivalent to `./launcher enter web_only`?

---

<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: [September 9, 2025, 9:55pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/119 "2025-09-09T21:55:55Z")

</div>

> [@merefield](#):
>
> this is equivalent to `./launcher enter web_only`?

Mostly. `./launcher` will do a git pull (at least I thought so, but maybe not?) first and you’re more likely to have tab-completion working for docker than `./launcher`.

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [September 9, 2025, 9:59pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/120 "2025-09-09T21:59:42Z")

</div>

It also places you at the root, whereas launcher puts you in the discourse directory

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [September 9, 2025, 10:01pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/121 "2025-09-09T22:01:44Z")

</div>

> [@pfaffman](#):
>
> ```plaintext
> docker exec -it web_only bash
> chown -R discourse:www-data /shared/backups`
> 
> ```

```plaintext
/var/www/discourse/public/backups# ls -l
total 4
drwxr-xr-x 2 discourse www-data 4096 Sep 6 12:37 default

```

that seems to make the right tweak, so lets see how we get on with next backup, thanks!

---

<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: [September 9, 2025, 10:11pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/122 "2025-09-09T22:11:21Z")

</div>

You can just run one now from the command line or the UX to see if it worked.

Also, if I’d been more clever:

```plaintext
docker exec -it web_only bash -c "chown -R discourse:www-data /shared/backups"

```

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [September 10, 2025, 10:49am UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/123 "2025-09-10T10:49:19Z")

</div>

I was patient and waited for the scheduled job and that appears to have worked, so many thanks for your help @pfaffman 🙏

I guess I’m just left wondering if this will happen to others and if there needs to be a change somewhere to prevent that?

---

<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: [September 10, 2025, 7:45pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/124 "2025-09-10T19:45:21Z")

</div>

> [@merefield](#):
>
> I was patient and waited

That’s how we’re different.

> [@merefield](#):
>
> I guess I’m just left wondering if this will happen to others and if there needs to be a change somewhere to prevent that?

Yeah. There used to be a `chown` that ran every rebuild, I’m pretty sure. It can take a while, and is almost always superfluous (except when it’s not). It doesn’t have anything to do with one- vs two-containers. I think it has to do with moving from one version of Debian for the base image to another version and the new version has differnt user mappings than the old one did.

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [October 17, 2025, 12:30pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/125 "2025-10-17T12:30:44Z")

</div>

Is `docker_manager` plugin not useful in this setup? - it’s always telling me to rebuild app!

---

<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: [October 17, 2025, 4:10pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/126 "2025-10-17T16:10:11Z")

</div>

I’m not sure what “this” is but both this topic and the one that I refer to are for a [Standard install](https://meta.discourse.org/t/142537?silent=true), so docker\_manager works as normal.

Docker\_manager isn’t related to the process of moving to another server, as you’ve got to build a new container.

It should force you to build a new app when there’s a change to the base image, which I think has been happening a fair amount lately. TBH, I’ve not quite figured out the mechanisms at play there.

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [October 17, 2025, 5:00pm UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/127 "2025-10-17T17:00:43Z")

</div>

so how I found this was after a bootstrap of web\_only and replace (destroy, start) I went to update after a single plugin change, only to be prompted to rebuild app!

---

<div class="post-metadata">

### Author: ![philh](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/philh/32/532740_2.png) [@philh](https://meta.discourse.org/u/philh)
#### Post date: [February 7, 2026, 3:52am UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/128 "2026-02-07T03:52:43Z")

</div>

`./launcher bootstrap data && ./launcher destroy data && ./launcher start data`

fails with error unless first stopping the data container with `./launcher stop data`

This occurs on instances created fresh with `./discourse-setup --two-container` and converted using the longer method.

In both cases  
`./launcher stop web_only && ./launcher rebuild data && ./launcher rebuild web_only`  
and  
`./launcher bootstrap web_only && ./launcher destroy web_only && ./launcher start web_only`

work as expected.

Am I missing something?

[data\_yml error.txt](https://meta.discourse.org/uploads/short-url/vatK8LooWlNVGq7zzH2TEhSHZUi.txt) (5.2 KB)  
[data\_yml error --two-container method.txt](https://meta.discourse.org/uploads/short-url/gXojaVRB5MTB2BQO8Z1maLLDTxG.txt) (5.0 KB)

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [February 7, 2026, 5:14am UTC](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413/129 "2026-02-07T05:14:08Z")

</div>

Yeah that log contains “postgres already running stop container”

This does suggest you must stop the container first before bootstrapping the data container.

Looks like the instructions are no longer valid?

That suggests also there will be more downtime during a complete rebuild. Luckily they are rarely required.

I assume you’ve had no problems once you did in fact stop the data container?

[Previous page](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413.md?page=5)

[Next page](https://meta.discourse.org/t/move-from-standalone-container-to-separate-web-and-data-containers/29413.md?page=7)
