在运行时将泊位要求添加到泊坞窗图像
我希望能够添加一些额外的要求,以创build一个自己的泊坞窗图像。 我的策略是使用CMD命令从dockerfile构build映像,该命令将在运行时使用已安装的卷执行“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我build立了图像:
sudo docker build -t test .
最后我尝试使用这个命令附加我的新需求:
sudo docker run -v $(pwd)/sourceCode:/root/sourceCode -it test /bin/bash
我的本地文件夹“sourceCode”内有一个有效的requirements.txt文件(它只包含一行值“gunicorn”)。 当我得到提示时,我可以看到需求文件在那里,但是如果我执行pip freeze命令,gunicorn软件包不在列表中。
为什么requirements.txt文件已经正确连接,但是pip命令无法正常工作?
TLDR
pip
命令没有运行,因为你告诉Docker运行/bin/bash
。
docker run -v $(pwd)/sourceCode:/root/sourceCode -it test /bin/bash ^ here
更长的解释
容器的默认ENTRYPOINT
是/bin/sh -c
。 你不要在Dockerfile中覆盖它,所以仍然存在。 默认的CMD
指令可能什么都不是。 你可以在你的Dockerfile中覆盖它。 运行时(为了简洁,忽略音量)
docker run -it test
什么实际上在容器内执行
/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 run
命令采取这种forms
docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]
进一步阅读
-
这个答案对
CMD
和ENTRYPOINT
指令的作用有一个真正的重点解释ENTRYPOINT
指定一个在容器启动时总是执行的命令。CMD
指定将被馈送到进入点的ENTRYPOINT
。 -
这篇博客文章介绍了
ENTRYPOINT
和CMD
指令之间的区别,值得一读。
您可以将最后一条语句(即CMD
更改为下面的语句。
– 在下面的语句中指定点位置的绝对path
CMD ["/usr/bin/pip", "install", "-r", "/root/sourceCode/requirements.txt"]
更新:根据评论添加额外的答案。
有一点必须注意,如果定制的图像需要额外的需求,那应该是图像的一部分,而不是在运行时进行。
使用下面的基本图像来testing:
docker pull colstrom/python:legacy
所以,安装包应该使用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"]
requirements.txt
selenium
用pip包构build映像希望您知道将Dockerfile,requirements.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.
现在运行映像如果你没有传递任何外部命令,那么容器从CMD
获取命令,这只是显示了pip
包的列表。 在这种情况下, selenium
。
D:\dockers\py1>docker run -itd --name testreq pypiptest 039972151eedbe388b50b2b4cd16af37b94e6d70febbcb5897ee58ef545b1435 D:\dockers\py1>docker logs testreq selenium==3.0.1
所以,上面显示的是软件包安装成功。
希望这是有帮助的。
使用@Rao和@ROMANARMY在他们的答案中已经解释的概念,我终于find了一种做我想做的事情的方式:为自创的docker镜像添加额外的python需求。
我的新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脚本,其中包含以下内容:
#!/bin/bash pip install -r /root/sourceCode/requirements.txt pip freeze > /root/sourceCode/freeze.txt
最后,我使用这些命令构build并运行映像:
docker build --tag test . docker run -itd --name container_test -v $(pwd)/sourceCode:/root/sourceCode test <- without any parameter at the end
正如我在文章开头解释的那样,我在本地文件夹中有一个名为sourceCode的文件夹,其中包含一个有效的requirements.txt文件,只有一行“gunicorn”
所以最后,我有能力添加一些额外的要求(在这个例子中的gunicorn包)到一个给定的docker图像。
build立和运行我的实验后如果我检查日志( docker logs container_test
),我看到这样的事情:
Downloading gunicorn-19.6.0-py2.py3-none-any.whl (114kB) 100% |################################| 122kB 1.1MB/s Installing collected packages: gunicorn
此外,容器已经在安装的卷中创build了一个freeze.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
现在我还有其他问题与新创build的文件的权限,但这可能会在一个新的职位。
谢谢!