nickjj / docker-flask-example

A production ready example Flask app that's using Docker and Docker Compose.
MIT License
583 stars 101 forks source link

cannot create directory ‘public/js’: Permission denied - Rootless docker #19

Open betopolione opened 6 months ago

betopolione commented 6 months ago

Hey Nick, first of all, thank you so much for this amazing repo, man, it is helping me a lot.

I just want to check with you if it is possible to run this repo in an env where docker is installed as rootless.

When I run docker compose up in my nixos, with "root-full" docker, everything works fine, but doesn`t work if I run in a rootless docker.

Will share here some outputs.

[beto@nixos:~/test/ruby_projects/docker-flask-example]$ docker compose run web mkdir public/js
[+] Building 0.0s (0/0)                                                                                                                                                                      docker:default
[+] Creating 2/0
 ✔ Container helloflask-redis-1     Created                                                                                                                                                            0.0s 
 ✔ Container helloflask-postgres-1  Created                                                                                                                                                            0.0s 
[+] Running 2/2
 ✔ Container helloflask-redis-1     Started                                                                                                                                                            0.3s 
 ✔ Container helloflask-postgres-1  Started                                                                                                                                                            0.3s 
[+] Building 0.0s (0/0)                                                                                                                                                                      docker:default
mkdir: cannot create directory ‘public/js’: Permission denied

[beto@nixos:~/test/ruby_projects/docker-flask-example]$ docker compose run web id
[+] Building 0.0s (0/0)                                                                                                                                                                      docker:default
[+] Creating 2/0
 ✔ Container helloflask-redis-1     Running                                                                                                                                                            0.0s 
 ✔ Container helloflask-postgres-1  Running                                                                                                                                                            0.0s 
[+] Building 0.0s (0/0)                                                                                                                                                                      docker:default
uid=1000(python) gid=1000(python) groups=1000(python)

[beto@nixos:~/test/ruby_projects/docker-flask-example]$ docker compose run js id
[+] Building 0.0s (0/0)                                                                                                                                                                      docker:default
[+] Building 0.0s (0/0)                                                                                                                                                                      docker:default
uid=1000(node) gid=1000(node) groups=1000(node)

[beto@nixos:~/test/ruby_projects/docker-flask-example]$ id
uid=1000(beto) gid=100(users) groups=100(users),1(wheel),57(networkmanager),1000(beto)

[beto@nixos:~/test/ruby_projects/docker-flask-example]$ docker compose run css id
[+] Building 0.0s (0/0)                                                                                                                                                                      docker:default
[+] Building 0.0s (0/0)                                                                                                                                                                      docker:default
uid=1000(node) gid=1000(node) groups=1000(node)

[beto@nixos:~/test/ruby_projects/docker-flask-example]$ ls -ln
total 104
-rw-r--r-- 1 1000 1000  1936 jan 17 15:18 alembic.ini
drwxr-xr-x 5 1000 1000  4096 jan 17 15:18 assets
drwxr-xr-x 2 1000 1000  4096 jan 17 15:18 bin
-rw-r--r-- 1 1000 1000 13853 jan 17 15:18 CHANGELOG.md
drwxr-xr-x 2 1000 1000  4096 jan 17 15:18 config
drwxr-xr-x 3 1000 1000  4096 jan 17 15:18 db
-rw-r--r-- 1 1000 1000  3278 jan 17 20:35 docker-compose.yml
-rw-r--r-- 1 1000 1000  2145 jan 17 15:18 Dockerfile
drwxr-xr-x 5 1000 1000  4096 jan 17 15:18 hello
drwxr-xr-x 2 1000 1000  4096 jan 17 15:18 lib
-rw-r--r-- 1 1000 1000  1108 jan 17 15:18 LICENSE
drwxr-xr-x 2 1000 1000  4096 jan 17 15:18 public
-rw-r--r-- 1 1000 1000   104 jan 17 15:18 pyproject.toml
-rw-r--r-- 1 1000 1000 18044 jan 17 15:18 README.md
-rw-r--r-- 1 1000 1000   850 jan 17 15:18 requirements-lock.txt
-rw-r--r-- 1 1000 1000   357 jan 17 15:18 requirements.txt
-rwxr-xr-x 1 1000 1000  4243 jan 17 15:18 run
drwxr-xr-x 3 1000 1000  4096 jan 17 15:18 test

I ask for your help, please.

Thanks in advance.

nickjj commented 6 months ago

Hi,

I think the issue here is your uid is 1000 but your gid is 100 based on your output of id.

This project expects your uid / gid to both be 1000 to work out of the box.

However, if you want to stick with a 100 gid user you can change the GID env var in your .env file to be 100 and re-build your image. This env var is documented in the env file too.

betopolione commented 6 months ago

Hi Nick, thanks for the quick answer, man.

For some reason, when I change the GID to 100, the build works, but the UP get an error saying that the group with ID 100 already exists inside the container.

Also, I created a VM with ubuntu, that has the GID 1000 by default and I get the same error. (But works fine if I run docker root full)

Let me know if you prefer to me to send some outputs here.

Thanks again!

nickjj commented 6 months ago

Did any of the files on disk end up with different permissions other than UID 1000 and GID 100 from the failed attempts of things running before? If so you might want to chown them back.

Based on your id output, it looks like your beto user isn't in the docker group. Can you add that? It's in Docker's official post installation steps for installing Docker on Linux.

If that doesn't work can you change that user's group ID to be something other than 100, preferably 1000+?

I never used Docker's rootless mode but I run native Linux on a few machines with a user who has UID / GID of 1000 and it works. This is with Docker running in its default root mode but it runs as a user on the system who's in the docker group so they can run all Docker commands without root.

betopolione commented 6 months ago

Hey Nick, answering your questions:

I think it fails when attempt to create the folder css/js inside the public folder (it didn´t even manage to create these folders because of permission denied)

Given that I am running non-root docker, it didn´t create the "docker" group. It uses a user docker daemon (I used this reference https://docs.docker.com/engine/security/rootless/)

I am using non-root because it prevents some security issues. When I add my user the docker group, using default root installation, even without using sudo, my user will have root privilegies, once the docker group is configured to manage the docker daemon installed as root.

I have the same issue when building with podman, because podman has the same limitation as docker non-root.

When I build using docker default root installation, everything works fine.

nickjj commented 6 months ago

The css/js files should get created on your host machine with the same permissions as whatever user lines up with your UID / GID. As far as I know root isn't needed for this.

I don't think getting this to work will result in any code changes within this repo. I'd suggest creating a super minimal example repo where you run anything as a non-root user with a volume and see if you encounter the same issue. If you do then you can propose it to Docker as an inability to run containers with rootless Docker.

In the mean time, the reason you have permission errors here is due to the volume mount. I don't know what environment you're planning to run this in but if you can get away without volumes (such as in production) then that could be an intermediate fix.

Or if it's running in development, maybe run Docker without rootless mode because it's your dev box and everything will work.

These things could temporarily happen in parallel while finding a proper solution.

betopolione commented 6 months ago

Thanks man, I will do some tests and post back here if I find some solution.

I think it has to do with this issue https://mydeveloperplanet.com/2022/10/19/docker-files-and-volumes-permission-denied/

Again, thank you for your work!

nickjj commented 6 months ago

No problem, if you find a solution let us know. Maybe we can drop in a FAQ item on steps you may need to take to get things to work with rootless Docker or Podman.

betopolione commented 6 months ago

Hello Nick, I'm still investigating the issue.

I just want to double-check something with you.

In the output below, shouldn't the Owner be 'node' instead of 'root'? Thanks

beto@beto-virtual-machine:~/docker-flask-example$ ~/bin/docker compose run js ls -l ..
total 104
-rw-rw-r-- 1 root root 13853 Jan 18 15:16 CHANGELOG.md
-rw-rw-r-- 1 root root  2145 Jan 18 20:02 Dockerfile
-rw-rw-r-- 1 root root  1108 Jan 18 15:16 LICENSE
-rw-rw-r-- 1 root root 18044 Jan 18 15:16 README.md
-rw-rw-r-- 1 root root  1936 Jan 18 15:16 alembic.ini
drwxrwxr-x 5 root root  4096 Jan 18 15:16 assets
drwxrwxr-x 2 root root  4096 Jan 18 15:16 bin
drwxrwxr-x 2 root root  4096 Jan 18 15:16 config
drwxrwxr-x 3 root root  4096 Jan 18 15:16 db
-rw-rw-r-- 1 root root  2618 Jan 18 15:16 docker-compose.yml
drwxrwxr-x 5 root root  4096 Jan 18 15:16 hello
drwxrwxr-x 2 root root  4096 Jan 18 15:16 lib
drwxrwxr-x 2 root root  4096 Jan 18 15:16 public
-rw-rw-r-- 1 root root   104 Jan 18 15:16 pyproject.toml
-rw-rw-r-- 1 root root   850 Jan 18 15:16 requirements-lock.txt
-rw-rw-r-- 1 root root   357 Jan 18 15:16 requirements.txt
-rwxrwxr-x 1 root root  4243 Jan 18 15:16 run
drwxrwxr-x 3 root root  4096 Jan 18 15:16 test
nickjj commented 6 months ago

Yes, it should be node:node there.

betopolione commented 6 months ago

I just run in docker root full mode and the output is the same.

Do you think this is the cause of the permission denied issue?

I dont have enough knowing of docker, sorry for all these questions

nickjj commented 6 months ago

It could be. I'd make sure the UID / GID lines up with what you want them to be and re-build the project. Then up it without using sudo.

betopolione commented 6 months ago

thanks man