# Install Discourse for development using Docker

**URL:** https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009
**Category:** Developer Guides
**Tags:** docker, dev-install, how-to
**Created:** [November 16, 2018, 9:40am UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009 "2018-11-16T09:40:04Z")
**Posts on this page:** 20
**Page:** 8

<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: [January 4, 2023, 9:38pm UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/232 "2023-01-04T21:38:33Z")

</div>

I’ve tried this on two machines now and both are failing with a permissions error.

```plaintext
pfaffman@shinytim:~/src/discourse-repos/discourse$ d/bundle install
Bundler 2.4.2 is running, but your lockfile was generated with 2.4.1. Installing Bundler 2.4.1 and restarting using that version.
Fetching gem metadata from https://rubygems.org/.
Fetching bundler 2.4.1

Retrying download gem from https://rubygems.org/ due to error (2/4): Bundler::PermissionError There was an error while trying to write to `/usr/local/lib/ruby/gems/3.1.0/cache/bundler-2.4.1.gem`. It is likely that you need to grant write permissions for that path.

Retrying download gem from https://rubygems.org/ due to error (3/4): Bundler::PermissionError There was an error while trying to write to `/usr/local/lib/ruby/gems/3.1.0/cache/bundler-2.4.1.gem`. It is likely that you need to grant write permissions for that path.

Retrying download gem from https://rubygems.org/ due to error (4/4): Bundler::PermissionError There was an error while trying to write to `/usr/local/lib/ruby/gems/3.1.0/cache/bundler-2.4.1.gem`. It is likely that you need to grant write permissions for that path.

There was an error installing the locked bundler version (2.4.1), rerun with the `--verbose` flag for more details. Going on using bundler 2.4.2.
Fetching gem metadata from https://rubygems.org/.........
Fetching https://github.com/discourse/mail.git
There was an error while trying to write to `/usr/local/lib/ruby/gems/3.1.0/cache/bundler/git`.
It is likely that you need to grant write permissions for that path.

```

---

<div class="post-metadata">

### Author: ![topological](https://avatars.discourse-cdn.com/v4/letter/t/b487fb/32.png) [@topological](https://meta.discourse.org/u/topological)
#### Post date: [January 6, 2023, 6:27am UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/233 "2023-01-06T06:27:37Z")

</div>

I met this problem too.

---

<div class="post-metadata">

### Author: ![Aleksey\_Bogdanov](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/aleksey_bogdanov/32/288040_2.png) [@Aleksey\_Bogdanov](https://meta.discourse.org/u/Aleksey_Bogdanov)
#### Post date: [January 9, 2023, 8:10am UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/234 "2023-01-09T08:10:51Z")

</div>

Any updates on this?

---

<div class="post-metadata">

### Author: ![musli123123](https://avatars.discourse-cdn.com/v4/letter/m/87869e/32.png) [@musli123123](https://meta.discourse.org/u/musli123123)
#### Post date: [January 9, 2023, 10:59pm UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/235 "2023-01-09T22:59:14Z")

</div>

Hello there,

I’m total new and noob. I try configure Discourse on dev Ubuntu 22.04 before ploy into GitHub and than server (no idea how but now it doesn’t matter)

I tried to install Dicourse locally using docker (using this tutorial).

I think i correctly intalled docker, but when i type:

sudo d/rails s

I get “[GitHub - discourse/mail: A Really Ruby Mail Library · GitHub](https://github.com/discourse/mail.git) is not yet checked out. Run `bundle install` first.”

and when i run

sudo d/bundle install

I get:  
“Fetching [GitHub - discourse/mail: A Really Ruby Mail Library · GitHub](https://github.com/discourse/mail.git)  
There was an error while trying to write to  
`/usr/local/lib/ruby/gems/3.1.0/cache/bundler/git`. It is likely that you need  
to grant write permissions for that path.”

Please advice 🙂

---

<div class="post-metadata">

### Author: ![ckjhdmmwxx](https://avatars.discourse-cdn.com/v4/letter/c/977dab/32.png) [@ckjhdmmwxx](https://meta.discourse.org/u/ckjhdmmwxx)
#### Post date: [January 10, 2023, 7:36pm UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/236 "2023-01-10T19:36:44Z")

</div>

Created a pull request to fix this - [Setting bundler version to 2.4.1 which is same as version that generated lockfile to avoid failing script by nkirit · Pull Request #665 · discourse/discourse\_docker · GitHub](https://github.com/discourse/discourse_docker/pull/665)

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [January 10, 2023, 8:44pm UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/237 "2023-01-10T20:44:40Z")

</div>

Thanks for the reports - this should be fixed by [this commit](https://github.com/discourse/discourse_docker/commit/1de36f60aeaf37e5764535062e2e67d68ae6fd7b)

The build [is running](https://github.com/discourse/discourse_docker/actions/runs/3887109727/jobs/6632985852) and so a new `discourse_dev:release` image should be pushed within the next hour. After that you’ll need to `d/shutdown_dev` and `d/boot_dev` to pick up the changes.

---

<div class="post-metadata">

### Author: ![MorphZan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/morphzan/32/67951_2.png) [@MorphZan](https://meta.discourse.org/u/MorphZan)
#### Post date: [February 3, 2023, 7:52pm UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/238 "2023-02-03T19:52:51Z")

</div>

How do you set/give this container a specific static ip address?

---

<div class="post-metadata">

### Author: ![zergov](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/zergov/32/293138_2.png) [@zergov](https://meta.discourse.org/u/zergov)
#### Post date: [February 11, 2023, 3:28am UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/239 "2023-02-11T03:28:27Z")

</div>

Hi! I had the same error.

I managed to fix it by going into `app/assets/javascripts` and running `yarn` before running `d/boot_dev --init`.

My hypothesis is that `d/boot_dev --init` assumes `node_modules` exists somewhere in its execution. This fails because its not if you just cloned the repo.

---

<div class="post-metadata">

### Author: ![MarcP](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/marcp/32/160184_2.png) [@MarcP](https://meta.discourse.org/u/MarcP)
#### Post date: [March 3, 2023, 5:12pm UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/240 "2023-03-03T17:12:10Z")

</div>

After following this tutorial on Ubuntu 22, the d/boot\_dev --init ends with the following output:

```plaintext
Migrating database...
rake aborted!
Discourse::Utils::CommandError: /src/lib/discourse.rb:137:in `exec': mkdir: cannot create directory ‘/src/public/plugins/’: Permission denied
/src/lib/discourse.rb:171:in `execute_command'
/src/lib/discourse.rb:137:in `exec'
/src/lib/discourse.rb:33:in `execute_command'
/src/lib/plugin/instance.rb:727:in `activate!'
/src/lib/discourse.rb:352:in `block in activate_plugins!'
/src/lib/discourse.rb:349:in `each'
/src/lib/discourse.rb:349:in `activate_plugins!'
/src/config/application.rb:216:in `block in <class:Application>'
/src/lib/plugin.rb:6:in `initialization_guard'
/src/config/application.rb:216:in `<class:Application>'
/src/config/application.rb:75:in `<module:Discourse>'
/src/config/application.rb:74:in `<main>'
<internal:/usr/local/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
<internal:/usr/local/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:37:in `require'
/home/discourse/.bundle/gems/ruby/3.2.0/gems/bootsnap-1.16.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
/src/Rakefile:7:in `<main>'
(See full trace by running task with --trace)

```

Is this tutorial still up-to-date?

---

<div class="post-metadata">

### Author: ![thoka](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/thoka/32/115652_2.png) [@thoka](https://meta.discourse.org/u/thoka)
#### Post date: [March 19, 2023, 10:13pm UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/241 "2023-03-19T22:13:16Z")

</div>

To execute the commands (`d/command`) without sudo, you have to add yourself to the `docker` group via

```plaintext
sudo adduser $(whoami) docker

```

and log in again.

---

<div class="post-metadata">

### Author: ![GregorSondermeier](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gregorsondermeier/32/299039_2.png) [@GregorSondermeier](https://meta.discourse.org/u/GregorSondermeier)
#### Post date: [March 22, 2023, 8:23am UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/242 "2023-03-22T08:23:28Z")

</div>

> [@MarcP](#):
>
> After following this tutorial on Ubuntu 22, the d/boot\_dev --init ends with the following output:

Hi,  
I’m having that exact same issue.

> [@thoka](#):
>
> To execute the commands (`d/command`) without sudo, you have to add yourself to the `docker` group via
> 
> ```plaintext
> sudo adduser $(whoami) docker
> 
> ```
> 
> and log in again.

I did that:  
I have added myself to the _docker_ group and rebooted the system. I verified with the `groups` command that I am indeed part of the _docker_ group.

Still this error keeps popping up.

I’m on Ubuntu 22.04 and I already had docker installed via docker desktop for other projects. The user account I’m working with does not have admin privileges (is not part of the sudo group), but I have access to an account that does. However I can’t use that other account for my daily work.  
Is that a problem?

---

<div class="post-metadata">

### Author: ![thoka](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/thoka/32/115652_2.png) [@thoka](https://meta.discourse.org/u/thoka)
#### Post date: [March 24, 2023, 6:53am UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/243 "2023-03-24T06:53:39Z")

</div>

> [@GregorSondermeier](#):
>
> I’m on Ubuntu 22.04 and I already had docker installed via docker desktop for other projects.

Hm. Are you on a bare metal Ubuntu 22.04 or running it as wsl vm ?

---

<div class="post-metadata">

### Author: ![GregorSondermeier](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gregorsondermeier/32/299039_2.png) [@GregorSondermeier](https://meta.discourse.org/u/GregorSondermeier)
#### Post date: [March 24, 2023, 10:13am UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/244 "2023-03-24T10:13:01Z")

</div>

Bare metal. Ubuntu 22.04 running natively on my work laptop.

I noticed the following:  
The container’s _/src_ folder is mounted to _/home/gregor/repos/discourse_ on my host machine:

 ![image](https://global.discourse-cdn.com/meta/original/4X/7/8/7/787ec6b5caeed919d78e8b8ecfce68792336fe93.png)

On my host machine, after pulling the git repo this folder belongs to me and my group:

```bash
repos $ whoami
gregor
repos $ groups
gregor docker
repos $ pwd
/home/gregor/repos
repos $ ll
[...]
drwxrwxr-x 21 gregor gregor 4096 Mär 24 10:57 discourse/
[...]

```

The `d/*` scripts execute all commands inside the docker container as the _discourse_ user ([see here](https://github.com/discourse/discourse/blob/main/bin/docker/exec#L5)). And that discourse user does not have write access to that mounted _/src_ folder.

```plaintext
rake aborted!
Discourse::Utils::CommandError: /src/lib/discourse.rb:137:in `exec': mkdir: cannot create directory ‘/src/public/plugins/’: Permission denied

```

 ![image](https://global.discourse-cdn.com/meta/original/4X/c/c/1/cc19545b1f48f3f94ece77e3414ebcbc904d7601.png)

I can reproduce this if I log in to the container and try to create folders in there. If I do it as the root user, it succeeds.

 ![image](https://global.discourse-cdn.com/meta/original/4X/8/c/3/8c36ebe4d235ce59e43c8cf9557b14fafc6ba71f.png)  
On my host machine:  
 ![image](https://global.discourse-cdn.com/meta/original/4X/3/c/2/3c286586ebb649e76fd8e0c0fca493cb23d0e03a.png)

If I do it as the discourse user, it fails:

 ![image](https://global.discourse-cdn.com/meta/original/4X/2/3/7/2373469e16992e3fc24be0e3d2ab33907c9b6632.png)

However, I can’t quite connect this together 🤔

---

<div class="post-metadata">

### Author: ![thoka](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/thoka/32/115652_2.png) [@thoka](https://meta.discourse.org/u/thoka)
#### Post date: [March 24, 2023, 10:54am UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/245 "2023-03-24T10:54:35Z")

</div>

Hm. I run ubuntu 22.04 inside wsl in windows:

After `d/shell`:

 ![image](https://global.discourse-cdn.com/meta/original/4X/5/e/f/5ef514b2d457e147b2075f046689021aaef3affb.png)

and

```plaintext
$ docker inspect -f "{{ .Mounts }}" discourse_dev
[{bind /home/toka/dv/discourse/discourse/data/postgres /shared/postgres_data delegated true rprivate}
 {bind /home/toka/dv/discourse/discourse /src delegated true rprivate}]

```

---

<div class="post-metadata">

### Author: ![ClawdiaWolf](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/clawdiawolf/32/262518_2.png) [@ClawdiaWolf](https://meta.discourse.org/u/ClawdiaWolf)
#### Post date: [March 24, 2023, 11:12am UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/246 "2023-03-24T11:12:58Z")

</div>

> [@GregorSondermeier](#):
>
> The `d/*` scripts execute all commands inside the docker container as the _discourse_ user ([see here](https://github.com/discourse/discourse/blob/main/bin/docker/exec#L5)). And that discourse user does not have write access to that mounted _/src_ folder.
> 
> ```plaintext
> 
> ```

Is your UID on the host different than 1000 by any chance? If so that’s where the issue is. The Discourse user inside Docker is UID 1000 so the host files need to be writable by UID 1000

---

<div class="post-metadata">

### Author: ![GregorSondermeier](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gregorsondermeier/32/299039_2.png) [@GregorSondermeier](https://meta.discourse.org/u/GregorSondermeier)
#### Post date: [March 24, 2023, 11:16am UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/247 "2023-03-24T11:16:30Z")

</div>

[This SO post](https://stackoverflow.com/a/45673309/3628926) has hinted me to the same direction as you did. I can confirm that both my _gregor_ user on the host machine and the _discourse_ user in the container have the same ID 1000.

---

<div class="post-metadata">

### Author: ![thoka](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/thoka/32/115652_2.png) [@thoka](https://meta.discourse.org/u/thoka)
#### Post date: [March 24, 2023, 11:52am UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/249 "2023-03-24T11:52:34Z")

</div>

What’s the output of `d/exec ls -lan` and `echo $UID`?

---

<div class="post-metadata">

### Author: ![GregorSondermeier](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gregorsondermeier/32/299039_2.png) [@GregorSondermeier](https://meta.discourse.org/u/GregorSondermeier)
#### Post date: [March 24, 2023, 11:57am UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/250 "2023-03-24T11:57:08Z")

</div>

After running `d/shell`:  
 ![image](https://global.discourse-cdn.com/meta/original/4X/1/9/d/19d2fe7c1fa5b48334bccf961540260991f802a5.png)  
I see that all files are owned by root and not by discourse like on your screenshot.

(I had a previous post which showed nobody/nogroup, which was misleading because I fiddled around with creating a _discourse_ user and group on my host machine, which led to no success. So I deleted the post)

---

<div class="post-metadata">

### Author: ![GregorSondermeier](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gregorsondermeier/32/299039_2.png) [@GregorSondermeier](https://meta.discourse.org/u/GregorSondermeier)
#### Post date: [March 24, 2023, 11:59am UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/251 "2023-03-24T11:59:36Z")

</div>

Indicates that all files inside _/src_ are owned by the root user.

 ![image](https://global.discourse-cdn.com/meta/original/4X/6/d/3/6d3fb2497296cd851a35e1c97534f8e6ad411383.png)  
(The discourse group comes from an earlier attempt which wasn’t fruitful)

Thanks a lot for your help btw. I feel a bit stupid, I must be missing some knowledge about the unix permission system.

---

<div class="post-metadata">

### Author: ![GregorSondermeier](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gregorsondermeier/32/299039_2.png) [@GregorSondermeier](https://meta.discourse.org/u/GregorSondermeier)
#### Post date: [March 27, 2023, 11:26am UTC](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009/252 "2023-03-27T11:26:51Z")

</div>

After much research and fiddling around I have learned that **Docker Desktop on Linux** is causing the permission issues.

You see, the Discourse application in the Docker container is run as as a non-root user, namely the [discourse](https://github.com/discourse/discourse/blob/main/bin/docker/exec#L5) user. But as written e.g. [here](https://forums.docker.com/t/bind-mount-permissions-unexpected-mounting-as-root-root/129328) and [here](https://stackoverflow.com/a/50820023/3628926):

> Docker Desktop on Linux runs a virtual machine and the containers will run inside that virtual machine. In that case you can’t just mount the host folder the same way into the containers, because you need to mount it first into the virtual machine.

So, as someone who is by all means not a Docker expert, I see two ways of addressing this issue:

**(1) Ditch Docker Desktop on Linux and run Docker natively instead**

This seems to be the most sustainable solution as I see that the discourse container seems to be designed to be used like that. I’m only hesistant because then I have to remember all the commands to manage my images, containers and resources. And, being a frontent dev, I’d rather fancy an UI to manage stuff. But I guess I have to approach this as an investment to learn more about Docker.

**OR**

**(2) Change ownership of the folders mounted into the container**

I managed to get this approach to work and successfully run Discourse locally from Docker Desktop, however I do see a bunch of warnings in the Terminal and therefore I’m not sure how sustainable this solution is in the long run.

This involves several steps:

**Step 1: Clone the Repo**

```sh
$ git clone https://github.com/discourse/discourse.git
$ cd discourse

```

**Step 2: Initialize Container**

From within the cloned _discourse_ folder on the host machine, execute:

```plaintext
$ d/boot_dev

```

What does it do? See [here](https://github.com/discourse/discourse/blob/main/bin/docker/boot_dev).  
**Important** : Omit the `--init` flag so that nothing will be done after the container creation.

**Step 3: Change owner of folders**

The discourse user within the docker container has the id `1000`. This guide assumes that your host machine’s user also has that same id. It might not break things if your host machine’s user has a different id, but I cannot test this and therefore can’t speak for this situation. You can find out your id by executing `id` or `echo $UID` in a linux terminal.

From your host machine, execute:

```sh
# open a shell in the docker container
$ d/shell

# you should already be in /src, bug just for good measure:
$ cd /src

# change the owner of /src to the discourse user and group
$ chown 1000:1000 .

# change the owner of all files and folders within /src to the discourse user and group (non-recursively)
$ chown 1000:1000 *

# recursively change the owner of almost all subfolders to the discourse user and group
# basically all folders except 'database', because that one belongs to the 'postgres' user and group
$ chown -R 1000:1000 app bin config d db docs documentation images lib log plugins public script spec test vendor

# verify that it has worked, should show the discourse user and group now
$ ls -l

# leave the container
$ exit

```

**Step 4: Continue as usual**

Continue setting up the container and starting Discourse by executing the following from your host machine:

```sh
# install gems
$ d/bundle install

# migrate database
$ d/rake db:migrate
$ RAILS_ENV=test d/rake db:migrate

# create admin user
$ d/rake admin:create

# In one terminal:
d/rails s

# And in a separate terminal
d/ember-cli

```

Note:  
I faced some warnings like this:  
`fatal: detected dubious ownership in repository at '/src'`  
Which comes from the Docker Desktop on Linux virtualization thing.

Do ignore these warnings, from your host machine, execute:

```plaintext
d/exec git config --global --add safe.directory /src

```

**Why does Docker Desktop for Linux run a VM?**

> **[FAQs for Docker Desktop for Linux](https://docs.docker.com/desktop/troubleshoot-and-support/faqs/linuxfaqs/)**
>
> Frequently asked questions for Docker Desktop for Linux

[Previous page](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009.md?page=7)

[Next page](https://meta.discourse.org/t/install-discourse-for-development-using-docker/102009.md?page=9)
