警告:以“root”用户身份运行pip

94

我正在使用Docker制作我的Python Django应用程序的简单图像。但是在构建容器的最后,它会抛出以下警告(我正在Ubuntu 20.04上构建它):

警告:以“root”用户身份运行pip可能会导致权限错误,并与系统软件包管理器产生冲突的行为。建议使用虚拟环境

如果我正在图像中安装Python要求,为什么会出现此警告?我正在使用以下命令构建我的镜像:

sudo docker build -t my_app:1 .

我应该担心pip报出的警告吗?因为我知道它可能会破坏我的系统。

这是我的Dockerfile:

FROM python:3.8-slim-buster

WORKDIR /app
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

4
npm 和其他工具也会给出错误/警告。不要在容器内以 root 身份运行,创建一个用户,在 Dockerfile 中使用该用户进行安装/构建/运行是良好的实践。 - Justin
2
如果我理解正确,Dockerfile 中的 RUN pip ... 命令默认由容器的 root 用户运行,无论哪个主机系统用户调用了 docker build ...。这就是为什么被接受的答案在 Dockerfile 中添加了一个新用户的原因。@justin 表示,在任何情况下创建一个新的 Docker 用户都是最佳实践,这非常有趣,也许并不广为人知。 - user550701
我的问题是针对原帖作者,不是针对 Justin。 - Karl Knechtel
5
你明白是什么导致该进程以root用户身份运行吗?实际上问题是Pip以'root'用户身份运行的原因。这并不是sudo造成的,而是docker的默认行为。如果你想让RUN命令不以root身份运行,你需要在Dockerfile中添加一个用户。 - user550701
4个回答

96

这种行为是在pip 21.1中作为一个“错误修复”引入的。

pip 22.1开始,您现在可以使用参数选择退出警告:

pip install --root-user-action=ignore
您可以通过使用环境来在容器中忽略此内容:
ENV PIP_ROOT_USER_ACTION=ignore

#11035


哈,修复了一个bug!用户体验又退化了。 - Kevin Buchs
正如其他答案提到的,而这个答案忽略了——这是在警告您关于一个糟糕的做法和您在Dockerfile中犯下的配置错误。 - pradyunsg
4
我不知道在一个容器中是否存在“不良实践”,这个容器被封装成一个沙盒环境。这是对最低公共分母的高度主观看法。@pradyunsg - Maximilian Burszley
将Python库安装为root用户并不是问题,但以root用户身份运行应用程序是有问题的。我建议的最佳做法是以root用户身份安装Python库和应用程序代码,然后再降低权限以非root用户身份运行应用程序。 - undefined

65

您的容器构建方式没有添加用户,因此所有操作都是以 root 用户身份进行的。

您可以通过执行以下操作创建一个用户并安装到该用户的主目录中:

FROM python:3.8.3-alpine

RUN pip install --upgrade pip

RUN adduser -D myuser
USER myuser
WORKDIR /home/myuser

COPY --chown=myuser:myuser requirements.txt requirements.txt
RUN pip install --user -r requirements.txt

ENV PATH="/home/myuser/.local/bin:${PATH}"

COPY --chown=myuser:myuser . .

CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

2
直到我将 RUN pip install --upgrade pip 移动到 USER myuser 之下,警告才消失。 - Mathilda
8
因为Ubuntu 18.04的adduser命令没有-D标志,所以我收到了“选项d不明确(debug、disabled-login、disabled-password)”的错误提示。 - user550701
7
一些人认为useradd更具可移植性,应该优先使用。 Dockerfile最佳实践也建议使用useradd - user550701
@alper 这不是一个错误,而是一个警告。所以它可以运行,只是提醒你确保你知道自己在做什么。 - markwalker_
1
最好这样称呼:pip install --upgrade pip >/dev/null 2>&1,以抑制警告,因为您知道自己在做什么。 - alper
显示剩余4条评论

34

更新 220930

好消息是你可以忽略这里的警告,但对于 pip 版本 > = 22.1,忽略该警告不再是最佳实践。在撰写本答案时,我还不知道 pip 版本 > = 22.1 的新技巧。

pip 版本 > = 22.1

请参考Maximilian Burszley的答案。在撰写本答案时,我还不知道这个方法,它允许您使用一个小参数避免警告。

pip 版本 > = 21.1 且 22.1

你可以忽略此警告,因为你创建的镜像是为了特定目的而隔离的,从组织上来看,就像虚拟环境一样隔离。虽然技术上不是,但这里并不重要。

通常应该不值得为了避免警告而投入时间创建虚拟环境或像另一个答案中添加用户,因为你不应该有任何问题。可能会在调试过程中影响视线,但不会停止代码工作。

只需检查 pip -Vpip3 -V,以了解是否需要注意不要错误地使用 python 2 的 pip,而想要用的是 python 3 的 pip。但这应该就是全部,如果你只安装 python 3 版本的 pip,则不会有这个问题。

pip版本 <21.1

在这些旧版本中,警告不会弹出,可以再次查看其他答案。同时从问题的年代也可以清楚地看出,在旧版本中并没有出现这个警告。


8
我也这么想。不知道是否有人对这个答案有异议!我计划不在我的Docker容器内拥有多个用户,顺带一提我是从Python:3.9继承的。我不明白为什么要在我的Dockerfile中创建用户!这样会增加维护难度! - Hossein Kalbasi
1
我一般反对“你可以忽略那个警告”的做法;在警告中堆积了许多“只是忽略掉”的东西之后,重要信息很容易就会被埋没。相反,按照Maximilian Burszley的回答所述,抑制掉你不想要的警告。 - cjs
1
@cjs 警告不是错误。虽然我想要消除任何警告,但我也不喜欢增加 Docker 设置的开销。这个答案更多地涉及你即使知道更好的做法,你会怎么做。如果你需要一个无警告的设置,请选择另一个答案,它已经得到了我的赞同。 - questionto42
1
@questionto42standswithUkraine 正确,警告不是错误。既然我们完全同意这一点,也许你应该以此为前提重新阅读我的答案。而且 Maximilian Burszley 的答案 对 Docker 设置没有任何额外负担。 - cjs
2
是的,你说得对;重新阅读后我发现警告出现在21.1中,抑制它的标志出现在22.1之后。(但我认为值得将你的第三部分标题从“pip版本<22.1”更改为“pip版本≥21.1且<22.1”,以防有人想知道为什么在某些情况下他们没有收到警告。) - cjs
显示剩余5条评论

13

我不喜欢忽略警告,因为有一天你可能会忽视一个重要的警告。

这里有一个关于Python最佳Docker实践的好解释。 搜索Example with virtualenv,你会找到以下内容:

# temp stage
FROM python:3.9-slim as builder

WORKDIR /app

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

RUN apt-get update && \
    apt-get install -y --no-install-recommends gcc

RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"

COPY requirements.txt .
RUN pip install -r requirements.txt


# final stage
FROM python:3.9-slim

COPY --from=builder /opt/venv /opt/venv

WORKDIR /app

ENV PATH="/opt/venv/bin:$PATH"

运行得非常好,没有任何警告或类似的问题。 顺便提一下,出于安全原因,他们还建议创建一个非root用户。

编辑:为了消除所有警告,您可能还想将以下条目添加到Dockerfile的构建器部分(适用于Debian 8.3.x):

ARG DEBIAN_FRONTEND=noninteractive
ARG DEBCONF_NOWARNINGS="yes"

RUN python -m pip install --upgrade pip && \
    ...

你为什么使用了 --no-install-recommends - alper
我无法告诉您核心原因,因为该标志是我答案中引用的解决方案使用的。这里是--no-install-recommends标志的一般解释:https://askubuntu.com/a/65093/737843。 - HeyMan
4
这是一个 Docker 镜像。它不应该被交互使用,因此你只需要安装必要的部分。 - MSalters
“--no-install-recommends” 是 apt-get 命令的一个 Debian 标志,因此它不会安装软件包的可选依赖项。详情请参见 https://unix.stackexchange.com/q/77053/16640。 - Franklin Piat
我仍然看到一个警告。 - Dmitrii Kalashnikov
我也可以像这样使用/usr/local而不是/optRUN python3 -m venv --system-site-packages /usr/local;这样做的话,通常不需要显式地在PATH中添加/usr/local/bin,因为它已经存在(虽然不能保证)。我认为它们两个都是合法的。另请参阅:https://unix.stackexchange.com/questions/11544/what-is-the-difference-between-opt-and-usr-local - nggit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接