向runtim中的docker映像添加pip需求

2024-05-14 01:18:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我想能够添加一些额外的要求到自己的创建docker图像。我的策略是使用CMD命令从dockerfile构建映像,该命令将在运行时使用装入的卷执行“pip install-r”命令。在

这是我的dockerfile:

FROM ubuntu:14.04

RUN apt-get update
RUN apt-get install -y python-pip python-dev build-essential 
RUN pip install --upgrade pip

WORKDIR /root

CMD ["pip install -r /root/sourceCode/requirements.txt"]

有了那个dockerfile我就可以建立一个形象:

^{pr2}$

最后,我尝试使用以下命令附加我的新需求:

sudo docker run -v $(pwd)/sourceCode:/root/sourceCode -it test /bin/bash

我的本地文件夹“sourceCode”中有一个有效的要求.txt文件(它只包含一行值为“gunicorn”)。 当我得到提示时,我可以看到需求文件在那里,但是如果我执行pip freeze命令,gunicorn包就不会被列出。在

为什么要求.txt文件已正确附加,但pip命令无法正常工作?在


Tags: installpip文件dockerrun图像命令dockerfile
3条回答

使用@Rao和@romanimary在他们的答案中解释过的概念,我终于找到了一种实现我想要的方法:将额外的python需求添加到自己创建的docker映像中。在

我的新Dockerfile如下:

FROM ubuntu:14.04

RUN apt-get update
RUN apt-get install -y python-pip python-dev build-essential 
RUN pip install  upgrade pip

WORKDIR /root

COPY install_req.sh .

CMD ["/bin/bash" , "install_req.sh"]

我添加了一个shell脚本的执行作为第一个命令,该脚本包含以下内容:

^{pr2}$

最后,我使用以下命令构建并运行映像:

docker build  tag test .
docker run -itd  name container_test -v $(pwd)/sourceCode:/root/sourceCode test <- without any parameter at the end

我在一个名为“本地”的文件夹的起始处解释了一个名为“我”的有效文件夹的源代码要求.txt只有一行“gunicorn”的文件

最后,我有能力向给定的docker映像添加一些额外的需求(本例中是gunicorn包)。在

在构建并运行我的实验之后,如果我检查日志(docker logs container_test),我会看到如下所示:

Downloading gunicorn-19.6.0-py2.py3-none-any.whl (114kB)
    100% |################################| 122kB 1.1MB/s 
Installing collected packages: gunicorn

此外,容器已经创建了一个冻结.txt装入卷内的文件,其中包含已安装的所有pip包,包括所需的gunicorn:

chardet==2.0.1
colorama==0.2.5
gunicorn==19.6.0
html5lib==0.999
requests==2.2.1
six==1.5.2
urllib3==1.7.1

现在我对新创建的文件的权限有其他问题,但这可能会出现在一篇新文章中。在

谢谢你!在

您可以将最后一个语句,即CMD更改为下面的语句。在

在下面的语句中指定pip位置的绝对路径

CMD ["/usr/bin/pip", "install", "-r", "/root/sourceCode/requirements.txt"]

更新:根据评论添加其他答案。在

必须注意的一点是,如果定制的映像需要附加的需求,那么这应该是映像的一部分,而不是在运行时执行。在

使用下面的基本图像进行测试:

^{pr2}$

因此,安装包应该使用Dockerfile的RUN命令来运行。
并且CMD应该被用来作为容器内的进程运行的应用程序。在

只需通过运行下面的命令检查基本映像是否有任何pip包,结果是什么都没有。在

docker run  rm  name=testpy colstrom/python:legacy /usr/bin/pip freeze

这个例子很简单:

Dockerfile

FROM colstrom/python:legacy
COPY requirements.txt /requirements.txt
RUN ["/usr/bin/pip", "install", "-r", "/requirements.txt"]
CMD ["/usr/bin/pip", "freeze"]

要求.txt

selenium

用pip包构建镜像希望你知道放置Dockerfile,要求.txt文件在新目录中。在

D:\dockers\py1>docker build -t pypiptest .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM colstrom/python:legacy
  -> 640409fadf3d
Step 2 : COPY requirements.txt /requirements.txt
  -> abbe03846376
Removing intermediate container c883642f06fb
Step 3 : RUN /usr/bin/pip install -r /requirements.txt
  -> Running in 1987b5d47171
Collecting selenium (from -r /requirements.txt (line 1))
  Downloading selenium-3.0.1-py2.py3-none-any.whl (913kB)
Installing collected packages: selenium
Successfully installed selenium-3.0.1
  -> f0bc90e6ac94
Removing intermediate container 1987b5d47171
Step 4 : CMD /usr/bin/pip freeze
  -> Running in 6c3435177a37
  -> dc1925a4f36d
Removing intermediate container 6c3435177a37
Successfully built dc1925a4f36d
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

现在运行图像 如果您没有传递任何外部命令,那么container从CMD获取命令,它只显示pip包的列表。在这个例子中,selenium。在

D:\dockers\py1>docker run -itd  name testreq pypiptest
039972151eedbe388b50b2b4cd16af37b94e6d70febbcb5897ee58ef545b1435

D:\dockers\py1>docker logs testreq
selenium==3.0.1

因此,以上说明包安装成功。在

希望这对你有帮助。在

TLDR

pip命令没有运行,因为您告诉Docker运行/bin/bash。在

docker run -v $(pwd)/sourceCode:/root/sourceCode -it test /bin/bash
                                                              ^
                                                             here

更长的解释

容器的默认ENTRYPOINT/bin/sh -c。在Dockerfile中不覆盖它,所以它仍然存在。默认的CMD指令可能是空的。你可以在你的Dockerfile中覆盖它。运行时(为简洁起见,请忽略音量)

^{pr2}$

在容器中实际执行的是

/bin/sh -c pip install -r /root/sourceCode/requirements.txt

很直接,当您启动容器时,看起来它将运行pip。在

现在让我们看一下您用来启动容器的命令(同样,忽略卷)

docker run -v -it test /bin/bash

在容器中实际执行的是

/bin/sh -c /bin/bash

您在Dockerfile中指定的CMD参数将被您在命令行中指定的COMMAND覆盖。回想一下docker runcommand takes this form

docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

进一步阅读

  1. This answerCMDENTRYPOINT指令的作用有一个非常切题的解释

    The ENTRYPOINT specifies a command that will always be executed when the container starts.

    The CMD specifies arguments that will be fed to the ENTRYPOINT.

  2. 这篇blog post关于ENTRYPOINTCMD指令之间的区别,值得一读。

相关问题 更多 >