Run Docker-compose as Root User: Python Coverage Permission Denied
I'm learning test-driven development with the course Microservices with Docker, Flask, and React.
It's been a lot of fun. I've also learned more about using Docker and docker-compose.
The course uses Coverage.py for measuring Python code coverage.
However, Coverage.py and Docker don't play well with each other if you run the Docker container as a normal (non-root) user.
PermissionError: [Errno 13] Permission denied: 'usr/src/app/.coverage'
Here is the Dockerfile:
# base imageFROM python:3.7.2-slim# install dependenciesRUN apt-get update && \apt-get -y install netcat && \apt-get clean# set working directoryWORKDIR /usr/src/app# add and install requirementsCOPY ./requirements.txt /usr/src/app/requirements.txtRUN pip install --upgrade pip && pip install -r requirements.txt# add entrypoint.shCOPY ./entrypoint.sh /usr/src/app/entrypoint.shRUN chmod +x /usr/src/app/entrypoint.sh# add appCOPY . /usr/src/app# add userRUN addgroup --system user && adduser --system --group userRUN chown -R user:user /usr/src/app && chmod -R 755 /usr/src/appUSER user# run serverCMD ["/usr/src/app/entrypoint.sh"]
As you can see, I add a normal user to the docker container, give them permission to the directory and run all following commands as non-root user.
Let's say I run this command:
docker-compose exec users python manage.py coverage
My docker-compose config doesn't specify a user. My Dockerfile (see above) switches to a non-root user.
Thus, my docker-compose commands run as non-root user.
docker-compose run --rm users -sh -c "id -u -n"> user
According to my research, it is more secure to run applications inside of the container as non-root user.
The important detail is to run applications inside of your container as a non-root user. It's the equivalent of systemd running as root and launching a program as a non-root user.
But now the permissions for Coverage.py don't work.
This seems to be a common problem: Test coverage in a docker container.
Trying to give permissions to the non-root user via
chmod +x doesn't work.
So, I need to run docker-compose as root user for Coverage.py.
I could add a
docker-compose.yml like so:
version: '3.7'services:users:user: rootbuild:context: ./services/usersdockerfile: Dockerfile(...rest of docker-compose file)
But I don't want to run all commands as root.
Instead it's possible to add a flag to the
docker-compose CLI command:
docker-compose run -u root --rm users sh -c "id -u -n">root
To run Coverage.py as root user:
docker-compose run -u root --rm users sh -c "python manage.py cov"