如何基于现有镜像创建新的 docker 镜像,但包含更多 Python 包?
Posted
技术标签:
【中文标题】如何基于现有镜像创建新的 docker 镜像,但包含更多 Python 包?【英文标题】:How to create a new docker image based on an existing image, but including more Python packages? 【发布时间】:2021-10-27 00:20:01 【问题描述】:假设我已经像这样提取了 NVIDIA NGC PyTorch docker 映像:
docker pull nvcr.io/nvidia/pytorch:21.07-py3
那我要添加这些python包:omegaconf wandb pycocotools
?
如何使用原始 Docker 映像和其他 Python 包创建新的 Docker 映像?
另外,我如何在整个组织中分发新图像?
【问题讨论】:
只需编写一个 Dockerfile,从 NVIDIA 映像开始并安装附加包。 @MarcelloRomani 好的,怎么样? 抱歉,这是家庭作业 :-) 一旦你知道如何编写一个基本的 Dockerfile 并安装几个 python 包,它就很简单了。 对一个问题投反对票的原因之一是:“这个问题没有显示出任何研究成果”。 @MarcelloRomani “没有表现出任何研究努力”的批评不再有意义,因为我现在已经回答了我自己的问题。这证明我做了足够的研究,不是吗? 【参考方案1】:创建一个名为Dockerfile
的文件。添加下面解释的行。
添加FROM
行来指定基础镜像:
FROM nvcr.io/nvidia/pytorch:21.07-py3
将 Pip 升级到最新版本:
RUN python -m pip install --upgrade pip
安装您需要的其他 Python 包:
RUN python -m pip install omegaconf wandb pycocotools
总的来说,Dockerfile 看起来像这样:
FROM nvcr.io/nvidia/pytorch:21.07-py3
RUN python -m pip install --upgrade pip
RUN python -m pip install omegaconf wandb pycocotools
在与Dockerfile
相同的目录中,运行此命令以构建新映像,将my-new-image
替换为您选择的名称:
docker build -t my-new-image .
这对我有用,但 Pip 会生成有关以 root 用户身份安装软件包的警告。我发现最好忽略这个警告。请参阅此答案末尾的注释以了解原因。
新的 docker 镜像现在应该出现在您的系统上:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-new-image latest 082f76972805 13 seconds ago 15.1GB
nvcr.io/nvidia/pytorch 21.07-py3 7beec3ff8d35 5 weeks ago 15GB
[...]
您现在可以运行新映像 ..
$ docker run --gpus all -it --rm --ipc=host my-new-image
.. 并验证它是否具有额外的 Python 包:
# python -m pip list | grep 'omegaconf\|wandb\|pycocotools'
omegaconf 2.1.1
pycocotools 2.0+nv0.5.1
wandb 0.12.1
The Docker Hub Repositories documentation 详细说明了以下必要步骤:
-
创建存储库(可能是私有的)
推送图片
添加协作者
从存储库中拉取图像
注意:非 root 用户的问题: 尽管不以 Docker 根用户身份运行 Docker 容器被认为是“最佳实践”,但实际上非 root 用户可能会增加一些复杂性.
你可以在你的 docker 文件中创建一个非 root 用户,如下所示:
RUN useradd -ms /bin/bash myuser
USER myuser
ENV PATH "$PATH:/home/myuser/.local/bin"
但是,如果您使用 -v
标志运行具有已安装卷的容器,则将根据其用户 ID 或组 ID 是否与主机系统中的用户或组匹配,授予 myuser
对这些卷的访问权限。您可以修改 useradd
命令行以指定所需的用户 ID 或组 ID,但生成的图像当然不能移植到具有不同 ID 的系统。
此外,似乎存在阻止非 root 用户访问指向 fscrypt
加密文件夹的已安装卷的限制。但是,这对我使用 root docker 用户来说很好。
由于这些原因,我发现让容器以 root 身份运行是最简单的。
【讨论】:
我从未见过使用python -m pip
添加 Python 包的示例 Dcokerfile,但我在这里使用它是因为我知道这是调用 Pip 的正确方法。当直接使用pip
命令时,有可能pip
和python
实际指向不同版本的Python。如果我们改用python -m pip
,就可以避免这种可能性。
出于好奇,我正在研究的一件事是,是否可以使用基本映像的包管理器安装这些 Python 包。这应该消除“不要将 pip 用作 root”警告。
这个最近的答案在 Dockerfile 中添加了一个新用户并在运行 Pip 之前切换到该用户。也建议先升级Pip:***.com/questions/68673221/…
显然 docker 最佳实践是不要在 docker 容器中使用 root 帐户。 docs.docker.com/develop/develop-images/…sysdig.com/blog/dockerfile-best-practices
非 root docker 用户根据与主机系统用户 ID 或组 ID 匹配的用户 ID 或组 ID 被授予对已挂载卷的文件访问权限。但是,如果 docker 映像假定主机系统具有具有特定 ID 的用户或组,则它们是不可移植的。此外,这似乎根本不适用于fscrypt
文件系统。只有 root docker 用户似乎能够访问未锁定的 fscrypt
文件系统中的文件。以上是关于如何基于现有镜像创建新的 docker 镜像,但包含更多 Python 包?的主要内容,如果未能解决你的问题,请参考以下文章