'Couldn't use data file .coverage: unable to open database file
A strange issue with permissions occured when pushing to GitHub. I have a test job which runs tests with coverage and then pushes results to codecov on every push and pull request. However, this scenario only works with root user.
If running with digitalshop user it throws an error:
Couldn't use data file '/digital-shop-app/.coverage': unable to open database file
My question is: how to run coverage in docker container so it won't throw this error? My guess is that it's because of permissions.
docker-compose.yml:
version: '3.9'
services:
test:
build: .
command: >
sh -c "
python manage.py wait_for_db &&
coverage run --source='.' manage.py test mainapp.tests &&
coverage report &&
coverage xml
"
volumes:
- ./digital-shop-app:/digital-shop-app
env_file: .env
depends_on:
- db
db:
image: postgres:13-alpine
environment:
- POSTGRES_DB=${DB_NAME}
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASS}
Dockerfile:
FROM python:3.9-alpine3.13
ENV PYTHONUNBUFFERED 1
COPY ./requirements.txt /requirements.txt
COPY ./digital-shop-app /digital-shop-app
COPY ./scripts /scripts
WORKDIR /digital-shop-app
RUN python -m venv /py && \
/py/bin/pip install --upgrade pip && \
apk add --no-cache bash && \
apk add --update --no-cache postgresql-client && \
apk add --update --no-cache --virtual .tmp-deps \
build-base jpeg-dev postgresql-dev musl-dev linux-headers \
zlib-dev libffi-dev openssl-dev python3-dev cargo && \
apk add --update --no-cache libjpeg && \
/py/bin/pip install -r /requirements.txt && \
apk del .tmp-deps && \
adduser --disabled-password --no-create-home digitalshop && \
chown -R digitalshop:digitalshop /py/lib/python3.9/site-packages && \
chmod -R +x /scripts
ENV PATH="/scripts:/py/bin:/py/lib:$PATH"
USER digitalshop
CMD ["run.sh"]
Solution 1:[1]
So I ended up creating another Dockerfile called Dockerfile.test and putting pretty much the same configuration except non-admin user creation. Here's the final variant:
Running code as root user is not recommended thus please read UPDATE section
Dockerfile.test:
FROM python:3.9-alpine3.13
ENV PYTHONUNBUFFERED 1
COPY ./requirements.txt /requirements.txt
COPY ./digital-shop-app /digital-shop-app
WORKDIR /digital-shop-app
RUN python -m venv /py && \
/py/bin/pip install --upgrade pip && \
apk add --no-cache bash curl gnupg coreutils && \
apk add --update --no-cache postgresql-client libjpeg && \
apk add --update --no-cache --virtual .tmp-deps \
build-base jpeg-dev postgresql-dev musl-dev linux-headers \
zlib-dev libffi-dev openssl-dev python3-dev cargo && \
/py/bin/pip install -r /requirements.txt && \
apk del .tmp-deps
ENV PATH="/py/bin:/py/lib:$PATH"
docker-compose.yml:
version: '3.9'
services:
test:
build:
context: .
dockerfile: Dockerfile.test
command: >
sh -c "
python manage.py wait_for_db &&
coverage run --source='.' manage.py test mainapp.tests &&
coverage report &&
coverage xml
"
volumes:
- ./digital-shop-app:/digital-shop-app
env_file: .env
depends_on:
- db
I don't know exactly whether it is a good practice. If not then please tell how to do it correctly.
UPDATE:
Thanks to @?.?????.?? for giving me food for thought.
After some local debugging I found out that coverage needs user to own the directory where .coverage file is located. So I created subdir named /cov inside project folder and set digitalshop user as its owner including everything inside. Finally I specified path to .coverage file by setting env variable COVERAGE_FILE=/digital-shop-app/cov/.coverage where digital-shop-app is project root folder. And also specified the same path to coverage.xml report in docker-compose.yml. Here's the code:
docker-compose.yml (added -o flag to coverage xml command):
version: '3.9'
services:
test:
build:
context: .
command: >
sh -c "
python manage.py wait_for_db &&
coverage run --source='.' manage.py test mainapp.tests &&
coverage xml -o /digital-shop-app/cov/coverage.xml
"
env_file: .env
depends_on:
- db
db:
image: postgres:13-alpine
environment:
- POSTGRES_DB=${DB_NAME}
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASS}
Dockerfile:
FROM python:3.9-alpine3.13
ENV PYTHONUNBUFFERED 1
COPY ./requirements.txt /requirements.txt
COPY ./digital-shop-app /digital-shop-app
COPY ./scripts /scripts
WORKDIR /digital-shop-app
RUN python -m venv /py && \
/py/bin/pip install --upgrade pip && \
apk add --no-cache bash && \
apk add --update --no-cache postgresql-client && \
apk add --update --no-cache --virtual .tmp-deps \
build-base jpeg-dev postgresql-dev musl-dev linux-headers \
zlib-dev libffi-dev openssl-dev python3-dev cargo && \
apk add --update --no-cache libjpeg && \
/py/bin/pip install -r /requirements.txt && \
apk del .tmp-deps && \
adduser --disabled-password --no-create-home digitalshop && \
chown -R digitalshop:digitalshop /py/lib/python3.9/site-packages && \
chmod -R +x /scripts && \
# New code here
mkdir -p /digital-shop-app/cov && \
chown -R digitalshop:digitalshop /digital-shop-app/cov
ENV PATH="/scripts:/py/bin:/py/lib:$PATH"
USER digitalshop
CMD ["run.sh"]
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
