Dockerfile配置非root用户时的pip与镜像构建问题求助
Docker非root用户运行pip的两类问题解决方法
问题1:构建wheel时脚本路径不在PATH的警告
构建过程中pep8、sqlformat、isort等工具提示脚本安装在/home/myuser/.local/bin但不在系统PATH中。
原因
切换到非root用户myuser后,pip install --user会将工具脚本安装到用户目录的.local/bin下,但原Dockerfile中ENV PATH的设置在pip install之后,且后续切换WORKDIR导致环境变量未正确生效,系统无法识别这些脚本路径。
修复方案
将ENV PATH="/home/myuser/.local/bin:${PATH}"提前到切换用户之后、执行pip install之前,确保安装工具时系统就能识别路径:
RUN adduser -D myuser USER myuser ENV PATH="/home/myuser/.local/bin:${PATH}" # 提前设置PATH WORKDIR /home/myuser COPY --chown=myuser:myuser requirements.txt requirements.txt RUN pip install --user -r requirements.txt
问题2:COPY wheels目录失败,提示文件不存在
执行COPY --from=builder /usr/src/app/wheels /wheels时报错,即使移除--wheel-dir参数也无法解决。
原因
/usr/src/app目录由root用户创建,切换到myuser后无该目录的写入权限,执行pip wheel时无法创建wheels目录,导致未生成wheel文件。
修复方案
有两种可选方式:
- 给myuser赋予/usr/src/app的写入权限
在切换用户前修改目录权限:
RUN adduser -D myuser RUN chown -R myuser:myuser /usr/src/app # 赋予myuser目录读写权限 USER myuser ENV PATH="/home/myuser/.local/bin:${PATH}" WORKDIR /usr/src/app # 保持工作目录在/usr/src/app COPY --chown=myuser:myuser requirements.txt . RUN pip install --user -r requirements.txt RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt
- 在myuser的home目录生成wheels
修改pip wheel的输出目录到myuser有权限的home目录,后续COPY时对应路径:
# builder阶段修改 USER myuser ENV PATH="/home/myuser/.local/bin:${PATH}" WORKDIR /home/myuser COPY --chown=myuser:myuser requirements.txt . RUN pip install --user -r requirements.txt RUN pip wheel --no-cache-dir --no-deps --wheel-dir /home/myuser/wheels -r requirements.txt # final阶段修改COPY路径 COPY --from=builder /home/myuser/wheels /wheels COPY --from=builder /home/myuser/requirements.txt .
完整修复后的Dockerfile示例
########### # BUILDER # ########### FROM python:3.9.4-alpine as builder WORKDIR /usr/src/app ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 # 安装编译依赖 RUN apk update \ && apk add postgresql-dev gcc python3-dev musl-dev # 代码检查 RUN pip install --upgrade pip RUN pip install flake8==3.9.2 COPY . . RUN flake8 --ignore=E501,F401 . # 创建非root用户并设置目录权限 RUN adduser -D myuser RUN chown -R myuser:myuser /usr/src/app USER myuser ENV PATH="/home/myuser/.local/bin:${PATH}" # 安装依赖并生成wheel包 COPY --chown=myuser:myuser requirements.txt . RUN pip install --user -r requirements.txt RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels -r requirements.txt ######### # FINAL # ######### FROM python:3.9.4-alpine # 创建app用户及目录 RUN mkdir -p /home/app RUN addgroup -S app && adduser -S app -G app ENV HOME=/home/app ENV APP_HOME=/home/app/web RUN mkdir $APP_HOME RUN mkdir $APP_HOME/staticfiles RUN mkdir $APP_HOME/mediafiles WORKDIR $APP_HOME # 安装系统依赖 RUN apk update && apk add libpq # 从builder阶段复制wheel包和依赖清单 COPY --from=builder /usr/src/app/wheels /wheels COPY --from=builder /usr/src/app/requirements.txt . RUN pip install --upgrade pip RUN pip install --no-cache /wheels/* # 配置启动脚本 COPY ./entrypoint.prod.sh . RUN sed -i 's/\r$//g' $APP_HOME/entrypoint.prod.sh RUN chmod +x $APP_HOME/entrypoint.prod.sh # 复制项目文件 COPY . $APP_HOME COPY ./media/ $APP_HOME/mediafiles # 设置文件权限 RUN chown -R app:app $APP_HOME USER app ENTRYPOINT ["/home/app/web/entrypoint.prod.sh"]
内容的提问来源于stack exchange,提问作者Tiltzer
相关产品推荐
相关产品推荐

