I have a container I am defining in a Dockerfile:
FROM python:3.9-alpine
WORKDIR /usr/app/
COPY src/backend/ .
RUN apk add acl
RUN pip install -r requirements.txt
RUN adduser -D game wheel
RUN setfacl -Rdm u:game:rwx /usr/app/
RUN chown -hR game /usr/app/ && chown -hR game /var/log/
USER game
HEALTHCHECK CMD curl --fail http://localhost:5000 || exit 1
CMD [ "python", "./src/app.py" ]
The intention is to run the container as 'game' user. The docker-compose file portion defining this service is this:
server:
container_name: "server"
user: game
build:
context: .
dockerfile: ./src/backend/Dockerfile
volumes:
- ./src/backend/:/usr/app
ports:
- 5000:5000
depends_on:
- redis
And the command to start the service:
sudo docker compose -f docker-compose.yml up -d --no-deps
However, the application fails when writing to log with this line:
PermissionError: [Errno 13] Permission denied: '/usr/app/log'
Even though the game user is owner of the /usr/app folder, it isn't permitted to write in it. I verified this by adding prints in the application of the current user, and it's permissions, and I saw the write permissions are missing. This isn't reproduced when running the Docker image without the compose. So it looks like it's related to how the compose runs the docker. What should be changed in the Docker definitions to allow the game user to write in this directory?
Quick answer: you are using volume
.
Long answer: When you run the container through Compose, your ./src/backend/
on host system is mounted to /usr/app
inside the container and it's owned by the user id and group id from your local system. You can check that quickly by doing exec
inside the container and doing ls -lah
. You will see all the files belonging to your user's user id group id (presumably 1000:1000
).
There are couple things you can do about it.
Forget the game
user and run as root. Why not?
Build your image with the source code, just COPY
it before you create the game
user and do chown
afterwards. You'll need to rebuild the image every time you want to run the new changes in the code.
Create the game
user with your user's user id and group id. This will possibly break portability. Bad solution.
Run the container, exec
into it and chown
again. This will break your local development for you though, as the files and directories in ./src/backend/
will be owned by whatever user id and group id game
has assigned.