nickjj / docker-rails-example

A production ready example Rails app that's using Docker and Docker Compose.
MIT License
941 stars 185 forks source link

Permission issue on second docker-compose up #47

Closed danielittlewood0 closed 1 year ago

danielittlewood0 commented 1 year ago

I could not use docker compose on my machine - I had to change to docker-compose everywhere. Otherwise I just followed the setup in the README.

On the first docker-compose up, everything worked fine. The server started, and I could visit it in a browser. The second time, I got multiple "permission denied" errors. I had to run chmod -R 777 . in order to be able to boot up.

Full backtrace: https://gist.github.com/danielittlewood0/a6762b0d411124bf6215da8a6573deed

nickjj commented 1 year ago

Hi,

What OS are you using and how did you install Docker / Docker Compose? I'm just wondering what prevented you from using docker compose.

Also if you run id from your terminal, what output do you get?

danielittlewood0 commented 1 year ago

@nickjj Gentoo linux; I installed docker ages ago but probably followed the instructions here: https://wiki.gentoo.org/wiki/Docker.

My docker version is 20.10.12 and my compose version is 1.29.2.

As for id:

$ id
uid=1001(daniel) gid=1001(daniel) groups=1001(daniel),7(lp),10(wheel),18(audio),19(cdrom),48(docker),85(usb),100(users),106(lpadmin),250(portage),272(plugdev)
nickjj commented 1 year ago

Ah. I haven't used Gentoo in a long time but it looks like Docker Compose v2 is available at https://packages.gentoo.org/packages/app-containers/docker-compose. That'll install Docker Compose as a Docker plugin.

But, your error here is related to having a uid:gid that's not 1000:1000. I've left more details here: https://github.com/nickjj/docker-django-example/issues/18, while it's a Django project the same thing applies to Rails since this is a Docker issue.

I'm a little surprised that 777 works here, were you able to successfully update a CSS or JS file and see the changes with your volume mount?

You can test this by opening app/assets/stylesheets/application.tailwind.css and adding this to the bottom:

body {
  background-color: #00ff00;
}

You should be able to reload your browser and see a green background. Who ends up owning files in the app/assets/builds/ directory?

It's a tricky problem because it's due to how volume mounts work combined with user permissions on the Docker host. There's not much I can do to properly fix this.

You may run into this issue continuously tho when new files are created by Rails. For example if you up the project and then run ./run rails g model hey do you get a permission error again?

danielittlewood0 commented 1 year ago

Thanks for bringing that to my attention! v2 is only available on the testing branch - I hadn't realised stable was so outdated :smiling_face_with_tear:

I am used to it being a file ownership issue - usually sudo chown -R daniel:daniel . will fix it - in this case I had to do chmod as well. I should have mentioned that I changed ownership first, but I was surprised that I had to do both.

I didn't update anything when I made the report. But I tried the update you suggested and refreshing didn't work; the server can't open this file for writing:

Permission denied @ apply2files - /app/tmp/cache/assets/sprockets/v4.0.0/yC/yCBlaVDE8E0WHr9DJ-e_2S6LI7Rl-32Jc_i6vGjq3Eo.cache

It's only when I chmod 777 again that it can access them (and then the screen changes colour). The owner of app/assets/builds is me - I guess if you are running the containers under user 1000 then it's not surprising that they can't write to my files.

I have seen this before with ownership issues, but I guess the containers I've been using run under root, where there is no issue for the container accessing files no matter who owns them.

Generating new files doesn't immediately raise problems for the server, but obviously I can't edit them. They're marked 644 and owned by user 1000 on my system.

I've never tried seriously to fix something like this (I don't tend to use rails generators, so the issue doesn't come up often). I guess one could provide a UID/GID at build time, and then at least the user who built the image could expect to be able to run it?

Nice project, by the way. And thanks for responding so quickly!

nickjj commented 1 year ago

It gets tricky because it has to be set at build time and every example project I have except for Rails uses a base Node image which creates a node user for you beforehand but it doesn't let you set the uid/gid, they hard code it to 1000.

Basically I would need some solution that works for all of my example apps. I guess based on https://github.com/nodejs/docker-node/issues/289#issuecomment-267081557 a solution might be possible with only needing UID/GID build args. I'll play around with it.

Generating new files doesn't immediately raise problems for the server, but obviously I can't edit them.

Right, this is a pretty big problem!

nickjj commented 1 year ago

Hey, can you please do me a favor and try out this PR and report back whether it works or not in that PR? https://github.com/nickjj/docker-flask-example/pull/7. You shouldn't have to chown anything, just modify the UID and GID values in the .env file to 1001:1001 and build + run it.

I know it's a Flask app and not Rails but I can do something similar for Rails too. I just want to make sure it works in that Flask example app because there's technically more moving parts than what it would be for this Rails app.

nickjj commented 1 year ago

This is fixed in: https://github.com/nickjj/docker-rails-example/commit/6f6984697de53854a2c8e354f7bf7e5c62420606