Install Discourse for development using Docker

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

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

I met this problem too.

1 Like

Any updates on this?

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

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

1 Like

Thanks for the reports - this should be fixed by this commit

The build is running 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.

4 Likes

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

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.

1 Like

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

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?

1 Like

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

sudo adduser $(whoami) docker

and log in again.

2 Likes

Hi,
I’m having that exact same issue.

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?

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

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:

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

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). And that discourse user does not have write access to that mounted /src folder.

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

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.


On my host machine:

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

However, I can’t quite connect this together :thinking:

Hm. I run ubuntu 22.04 inside wsl in windows:

After d/shell:

and

$ 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}]

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

This SO post 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.

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

After running d/shell:
image
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)

Indicates that all files inside /src are owned by the root user.
image
(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.

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