Install Discourse for development using Docker

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 user. But as written e.g. here and here:

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

$ 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:

$ d/boot_dev

What does it do? See here.
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:

# 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:

# 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:

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

Why does Docker Desktop for Linux run a VM?

2 Likes

Same, it errors when trying to bake the admin user profile. It works after adding a step to yarn install before creating the admin as suggested by @zergov. I went ahead and created a PR to add it: DEV: Yarn install to avoid error creating the admin user. by dsims · Pull Request #20866 · discourse/discourse · GitHub

Follow-up:
Docker Rootless mode causes the same permission mapping issues on Linux as Docker Desktop. The workaround I posted will work with this configuration, too.

However, I’m not super confident with the workaround, so I switched to a native Docker installation on my Linux system, added my non-sudo user to the docker group and now the permissions are mapped correctly inside the container and I can run docker commands without sudo.

Thanks @dsims, I just merged the PR :raised_hands:

1 Like

I get this far when using podman (trying to run d/boot_dev --init):

Installing gems...
Error response from daemon: environment variable "RAILS_ENV" badly formed, must be key=value

I guess I’ll need to use the native development environment approach as I’m not going to install docker on my Fedora desktop as it has been really broken for years now (with random stuff like pushing not working) and podman works so much better without any hassle (for projects that support it).

error
error Could not write file “/src/app/assets/javascripts/discourse/yarn-error.log”: “EACCES: permission denied, open ‘/src/app/assets/javascripts/discourse/yarn-error.log’”
error An unexpected error occurred: “EACCES: permission denied, mkdir ‘/src/app/assets/javascripts/node_modules’”.

Why do I get this error following by d/boot_dev --init?

3.0" has incorrect peer dependency "@uppy/core@^3.2.1".
[4/4] Building fresh packages...
$ ../run-patch-package
patch-package 8.0.0
Applying patches...
@ember/jquery@2.0.0 ✔
babel-plugin-debug-macros@0.3.4 ✔
content-tag@1.1.1 ✔
ember-source@3.28.12 ✔
ember-this-fallback@0.3.1 (1 initial) ✔
ember-this-fallback@0.3.1 (2 themes) ✔
virtual-dom@2.1.1 ✔
Done in 101.54s.
Migrating database...
rake aborted!
Discourse::Utils::CommandError: /src/lib/discourse.rb:138:in `exec': node:internal/modules/cjs/loader:1080
  throw err;
  ^

Error: Cannot find module 'esbuild'
Require stack:
- /src/app/assets/javascripts/theme-transpiler/build.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1077:15)
    at Module._load (node:internal/modules/cjs/loader:922:27)
    at Module.require (node:internal/modules/cjs/loader:1143:19)
    at require (node:internal/modules/cjs/helpers:121:18)
    at Object.<anonymous> (/src/app/assets/javascripts/theme-transpiler/build.js:3:17)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Module._load (node:internal/modules/cjs/loader:960:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/src/app/assets/javascripts/theme-transpiler/build.js' ]
}

Node.js v18.17.1
/src/lib/discourse.rb:172:in `execute_command'
/src/lib/discourse.rb:138:in `exec'
/src/lib/discourse.rb:34:in `execute_command'
/src/lib/discourse_js_processor.rb:119:in `build_theme_transpiler'
/src/lib/tasks/assets.rake:313:in `block in <main>'
Tasks: TOP => db:migrate => assets:precompile:theme_transpiler
(See full trace by running task with --trace)

Possibly related to this: Install Discourse for development using Docker - #239 by zergov

Maybe try going to the /var/www/discourse directory and running:

yarn install

Does anybody have some benchmarks about it?

I give a search in this topic but I didn’t found this specifically. I wonder if someone tried the normal and docker installation to compare between them :slight_smile:

A few hints for those who are trying to use the procedure described in this topic:

  1. Step 1 didn’t work for me. In order to install Docker, I had to use the “convenience script” describe here: Install Docker Engine on Ubuntu | Docker Docs

  2. You need sudo for all commands

  3. There seems to be a missing step 3: you need to create an admin user account. To create a new admin, run the following command: sudo d/rails admin:create

  4. As stated in the topic, if you use WSL, symlinks to the Windows file system won’t work. If you try anyway, you’ll break the install and end up with missing gems. To get your gems back, run: sudo d/bundle install

2 Likes

Hello.

I’m trying to install the development in a Debian 12.

When I run the command…

d/boot_dev --init

… after a while the following error appears:

$ ../run-patch-package
patch-package 8.0.0
Applying patches...
@ember/jquery@2.0.0 ✔
babel-plugin-debug-macros@0.3.4 ✔
content-tag@1.1.2 ✔
ember-source@3.28.12 ✔
ember-this-fallback@0.4.0 (1 deprecation-name) ✔
ember-this-fallback@0.4.0 (2 themes) ✔
virtual-dom@2.1.1 ✔
Done in 70.39s.
Migrating database...
rake aborted!
Discourse::Utils::CommandError: /src/lib/discourse.rb:138:in `exec': node:internal/modules/cjs/loader:1080
  throw err;
  ^

Error: Cannot find module 'esbuild'
Require stack:
- /src/app/assets/javascripts/theme-transpiler/build.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1077:15)
    at Module._load (node:internal/modules/cjs/loader:922:27)
    at Module.require (node:internal/modules/cjs/loader:1143:19)
    at require (node:internal/modules/cjs/helpers:121:18)
    at Object.<anonymous> (/src/app/assets/javascripts/theme-transpiler/build.js:3:17)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Module._load (node:internal/modules/cjs/loader:960:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/src/app/assets/javascripts/theme-transpiler/build.js' ]
}

Node.js v18.17.1
/src/lib/discourse.rb:172:in `execute_command'
/src/lib/discourse.rb:138:in `exec'
/src/lib/discourse.rb:34:in `execute_command'
/src/lib/discourse_js_processor.rb:119:in `build_theme_transpiler'
/src/lib/tasks/assets.rake:313:in `block in <main>'
Tasks: TOP => db:migrate => assets:precompile:theme_transpiler
(See full trace by running task with --trace)```

Am I doing something wrong?
1 Like
yarn install # this will reinstall everything including esbuild
# removing previously error installed container
docker stop discourse_dev
docker rm discourse_dev
d/boot_dev --init
# It will prompt you input admin email if succeed.

Hello. After having placed a symlink in the discourse/plugin directory and then restarting:

$ d/rails s

I get the following error:

https://github.com/rails/sprockets (at 3.x@f4d3dae) is not yet checked out. Run `bundle install` first

“Bundle install” does not resolve the issue. I’ve tried a bunch of things, but nothing seems to resolve this. If I remove the symlink in the plugins directory and restart, everything works fine again. I’ve tried it with different official plugins that I know are working on other discourse installations.

Anyone knows why this happens?

1 Like

Can you try d/bundle install instead?

1 Like

I can run d/bundle install, that works and I can then start everything, but the plugin doesn’t appear installed in discourse.

So I run d/shutdown_dev; d/boot_dev but after that it gives the old error message again https://github.com/rails/sprockets (at 3.x@f4d3dae) is not yet checked out. Run `bundle install` first

vOv

I have improved this in

It is definitely confusing to keep having to run d/bundle install manually each time you boot the dev environment. In the mean time, you will unfortunately have to run d/bundle install each time you run d/boot_dev.

3 Likes

I keep getting this error.

error Could not write file “/src/app/assets/javascripts/discourse/yarn-error.log”: “EACCES: permission denied, open ‘/src/app/assets/javascripts/discourse/yarn-error.log’”

error An unexpected error occurred: “EACCES: permission denied, mkdir ‘/src/app/assets/javascripts/node_modules’”.

hmmm :thinking: I think that is the same one as here - can’t find where it was resolved anywhere tho.

1 Like

Are you running this as a non-root user without sudo?

It was the root user.