无法使用数据文件.coverage:无法打开数据库文件

Lom*_*ank 6 python code-coverage dockerfile alpine-linux

推送到 GitHub 时出现奇怪的权限问题。我有一个测试作业,它运行覆盖范围的测试,然后在每次推送和拉取请求时将结果推送到 codecov。但是,这种情况仅适用于 root 用户。

如果与digitalshop用户一起运行,则会抛出错误:

Couldn't use data file '/digital-shop-app/.coverage': unable to open database file
Run Code Online (Sandbox Code Playgroud)

我的问题是:如何在 docker 容器中运行覆盖率,这样它就不会抛出此错误?我的猜测是这是因为权限。

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}
Run Code Online (Sandbox Code Playgroud)

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"]
Run Code Online (Sandbox Code Playgroud)

Lom*_*ank 1

因此,我最终创建了另一个名为的 Dockerfile Dockerfile.test,并放置了几乎相同的配置(除了非管理员用户创建之外)。这是最终的变体:

\n

不建议以 root 用户身份运行代码,因此请阅读更新部分

\n

Dockerfile.测试:

\n
FROM python:3.9-alpine3.13\n\nENV PYTHONUNBUFFERED 1\n\nCOPY ./requirements.txt /requirements.txt\nCOPY ./digital-shop-app /digital-shop-app\n\nWORKDIR /digital-shop-app\n\nRUN python -m venv /py && \\\n    /py/bin/pip install --upgrade pip && \\\n    apk add --no-cache bash curl gnupg coreutils && \\\n    apk add --update --no-cache postgresql-client libjpeg && \\\n    apk add --update --no-cache --virtual .tmp-deps \\\n        build-base jpeg-dev postgresql-dev musl-dev linux-headers \\\n        zlib-dev libffi-dev openssl-dev python3-dev cargo && \\\n    /py/bin/pip install -r /requirements.txt && \\\n    apk del .tmp-deps\n\nENV PATH="/py/bin:/py/lib:$PATH"\n
Run Code Online (Sandbox Code Playgroud)\n

docker-compose.yml:

\n
version: \'3.9\'\n\nservices:\n  test:\n    build:\n      context: .\n      dockerfile: Dockerfile.test\n    command: >\n      sh -c "\n        python manage.py wait_for_db &&\n        coverage run --source=\'.\' manage.py test mainapp.tests &&\n        coverage report &&\n        coverage xml\n      "\n    volumes: \n      - ./digital-shop-app:/digital-shop-app\n    env_file: .env\n    depends_on: \n      - db\n
Run Code Online (Sandbox Code Playgroud)\n

我不知道这是否是一个好的做法。如果没有,请告诉我如何正确地做到这一点。

\n

更新:

\n

感谢@\xce\xb2.\xce\xb5\xce\xb7\xce\xbf\xce\xb9\xcf\x84.\xce\xb2\xce\xb5给了我深思。

\n

经过一些本地调试后,我发现覆盖范围需要用户拥有.coverage文件所在的目录。/cov因此,我在项目文件夹内创建了名为的子目录,并将digitalshop用户设置为其所有者,包括其中的所有内容。最后,我.coverage通过设置环境变量来指定文件路径COVERAGE_FILE=/digital-shop-app/cov/.coverage,其中digital-shop-app是项目根文件夹。并且还指定了相同的路径来coverage.xml报告docker-compose.yml。这是代码:

\n

docker-compose.yml(-o向命令添加标志coverage xml):

\n
version: \'3.9\'\n\nservices:\n  test:\n    build:\n      context: .\n    command: >\n      sh -c "\n        python manage.py wait_for_db &&\n        coverage run --source=\'.\' manage.py test mainapp.tests &&\n        coverage xml -o /digital-shop-app/cov/coverage.xml\n      "\n    env_file: .env\n    depends_on: \n      - db\n\n  db:\n    image: postgres:13-alpine\n    environment:\n      - POSTGRES_DB=${DB_NAME}\n      - POSTGRES_USER=${DB_USER}\n      - POSTGRES_PASSWORD=${DB_PASS}\n
Run Code Online (Sandbox Code Playgroud)\n

Dockerfile:

\n
FROM python:3.9-alpine3.13\n\nENV PYTHONUNBUFFERED 1\n\nCOPY ./requirements.txt /requirements.txt\nCOPY ./digital-shop-app /digital-shop-app\nCOPY ./scripts /scripts\n\nWORKDIR /digital-shop-app\n\nRUN python -m venv /py && \\\n    /py/bin/pip install --upgrade pip && \\\n    apk add --no-cache bash && \\\n    apk add --update --no-cache postgresql-client && \\\n    apk add --update --no-cache --virtual .tmp-deps \\\n        build-base jpeg-dev postgresql-dev musl-dev linux-headers \\\n        zlib-dev libffi-dev openssl-dev python3-dev cargo && \\\n    apk add --update --no-cache libjpeg && \\\n    /py/bin/pip install -r /requirements.txt && \\\n    apk del .tmp-deps && \\\n    adduser --disabled-password --no-create-home digitalshop && \\\n    chown -R digitalshop:digitalshop /py/lib/python3.9/site-packages && \\\n    chmod -R +x /scripts && \\\n    # New code here\n    mkdir -p /digital-shop-app/cov && \\\n    chown -R digitalshop:digitalshop /digital-shop-app/cov\n\nENV PATH="/scripts:/py/bin:/py/lib:$PATH"\n\nUSER digitalshop\n\nCMD ["run.sh"]\n
Run Code Online (Sandbox Code Playgroud)\n

  • 不,您确实不应该使用 root 运行容器。但您缺少 [mre],因此我们可以重现并帮助您。 (2认同)