当前位置: 首页 > 面试题库 >

为Python项目构建Docker映像时如何避免重新安装软件包?

从阎宝
2023-03-14
问题内容

我的Dockerfile就像

FROM my/base

ADD . /srv
RUN pip install -r requirements.txt
RUN python setup.py install

ENTRYPOINT ["run_server"]

每次构建新映像时,都必须重新安装依赖项,这在我所在的地区可能非常慢。

我想到的cache已安装软件包的一种方法是my/base用较新的图像覆盖该图像,如下所示:

docker build -t new_image_1 .
docker tag new_image_1 my/base

因此,下一次我使用此Dockerfile进行构建时,我/基础已经安装了一些软件包。

但是此解决方案有两个问题:

  1. 并非总是可以覆盖基本图像
  2. 随着新图像的叠加,基础图像变得越来越大

那么我可以使用什么更好的解决方案来解决这个问题呢?

编辑##:

有关我机器上的docker的一些信息:

☁  test  docker version
Client version: 1.1.2
Client API version: 1.13
Go version (client): go1.2.1
Git commit (client): d84a070
Server version: 1.1.2
Server API version: 1.13
Go version (server): go1.2.1
Git commit (server): d84a070
☁  test  docker info
Containers: 0
Images: 56
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Dirs: 56
Execution Driver: native-0.2
Kernel Version: 3.13.0-29-generic
WARNING: No swap limit support

问题答案:

尝试使用以下Dockerfile进行构建。

FROM my/base

WORKDIR /srv
ADD ./requirements.txt /srv/requirements.txt
RUN pip install -r requirements.txt
ADD . /srv
RUN python setup.py install

ENTRYPOINT ["run_server"]

如果.(您的项目)有某些更改,则docker pip install通过使用缓存跳过行。

Docker仅pip install在您编辑requirements.txt文件时在构建上运行。

我写简单的Hello, World!程序。

$ tree
.
├── Dockerfile
├── requirements.txt
└── run.py

0 directories, 3 file

# Dockerfile

FROM dockerfile/python
WORKDIR /srv
ADD ./requirements.txt /srv/requirements.txt
RUN pip install -r requirements.txt
ADD . /srv
CMD python /srv/run.py

# requirements.txt
pytest==2.3.4

# run.py
print("Hello, World")

下面是输出。

Step 1 : WORKDIR /srv
---> Running in 22d725d22e10
---> 55768a00fd94
Removing intermediate container 22d725d22e10
Step 2 : ADD ./requirements.txt /srv/requirements.txt
---> 968a7c3a4483
Removing intermediate container 5f4e01f290fd
Step 3 : RUN pip install -r requirements.txt
---> Running in 08188205e92b
Downloading/unpacking pytest==2.3.4 (from -r requirements.txt (line 1))
  Running setup.py (path:/tmp/pip_build_root/pytest/setup.py) egg_info for package pytest
....
Cleaning up...
---> bf5c154b87c9
Removing intermediate container 08188205e92b
Step 4 : ADD . /srv
---> 3002a3a67e72
Removing intermediate container 83defd1851d0
Step 5 : CMD python /srv/run.py
---> Running in 11e69b887341
---> 5c0e7e3726d6
Removing intermediate container 11e69b887341
Successfully built 5c0e7e3726d6

我只更新run.py并尝试再次构建。

# run.py
print("Hello, Python")

下面是输出。

Sending build context to Docker daemon  5.12 kB
Sending build context to Docker daemon 
Step 0 : FROM dockerfile/python
---> f86d6993fc7b
Step 1 : WORKDIR /srv
---> Using cache
---> 55768a00fd94
Step 2 : ADD ./requirements.txt /srv/requirements.txt
---> Using cache
---> 968a7c3a4483
Step 3 : RUN pip install -r requirements.txt
---> Using cache
---> bf5c154b87c9
Step 4 : ADD . /srv
---> 9cc7508034d6
Removing intermediate container 0d7cf71eb05e
Step 5 : CMD python /srv/run.py
---> Running in f25c21135010
---> 4ffab7bc66c7
Removing intermediate container f25c21135010
Successfully built 4ffab7bc66c7

正如您在上面看到的,Docker使用构建缓存。这次我更新了requirements.txt。

# requirements.txt

pytest==2.3.4
ipython

下面是输出。

Sending build context to Docker daemon  5.12 kB
Sending build context to Docker daemon 
Step 0 : FROM dockerfile/python
---> f86d6993fc7b
Step 1 : WORKDIR /srv
---> Using cache
---> 55768a00fd94
Step 2 : ADD ./requirements.txt /srv/requirements.txt
---> b6c19f0643b5
Removing intermediate container a4d9cb37dff0
Step 3 : RUN pip install -r requirements.txt
---> Running in 4b7a85a64c33
Downloading/unpacking pytest==2.3.4 (from -r requirements.txt (line 1))
  Running setup.py (path:/tmp/pip_build_root/pytest/setup.py) egg_info for package pytest

Downloading/unpacking ipython (from -r requirements.txt (line 2))
Downloading/unpacking py>=1.4.12 (from pytest==2.3.4->-r requirements.txt (line 1))
  Running setup.py (path:/tmp/pip_build_root/py/setup.py) egg_info for package py

Installing collected packages: pytest, ipython, py
  Running setup.py install for pytest

Installing py.test script to /usr/local/bin
Installing py.test-2.7 script to /usr/local/bin
  Running setup.py install for py

Successfully installed pytest ipython py
Cleaning up...
---> 23a1af3df8ed
Removing intermediate container 4b7a85a64c33
Step 4 : ADD . /srv
---> d8ae270eca35
Removing intermediate container 7f003ebc3179
Step 5 : CMD python /srv/run.py
---> Running in 510359cf9e12
---> e42fc9121a77
Removing intermediate container 510359cf9e12
Successfully built e42fc9121a77

码头工人不使用构建缓存。如果它不起作用,请检查您的码头工人版本。

Client version: 1.1.2
Client API version: 1.13
Go version (client): go1.2.1
Git commit (client): d84a070
Server version: 1.1.2
Server API version: 1.13
Go version (server): go1.2.1
Git commit (server): d84a070


 类似资料:
  • 我的Dockerfile有点像 每次构建新映像时,都必须重新安装依赖项,这在我的区域可能会非常慢。 我想到的一种缓存已安装的软件包的方法是用以下更新的图像覆盖我的基本图像: 所以下次我用这个Dockerfile构建时,我的/base已经安装了一些包。 但这种解决方案有两个问题: 并不总是可以覆盖基本映像 随着新图像的分层,基本图像变得越来越大 那么,我可以用什么更好的解决方案来解决这个问题呢? 关

  • 问题内容: 我想创建一个docker镜像并正确安装,因此我选择具有这些属性的基础镜像。因此,的第一行如下: 然后下一个命令是 在创建docker映像时创建了以下错误: 如何能够在此docker映像中安装? 问题答案: 如提示: 获取(13:权限被拒绝) 我相信这是由于您的基本形象: https://github.com/SeleniumHQ/docker- selenium/blob/master

  • 我有一个GitHub项目(我正在使用它(我没有创建它)),名为OpenRefine,我想将其封装在Docker映像中,这样其他人就可以从“Docker Hub”中提取该Docker映像,并将OpenRefine安装在他们的基本交互Docker实体上,即。形象 然后我想将它上传到一个我可以与其他人共享的存储库。 如果它有一个名字,而不是一个疯狂的散列值,那就好了。 是不是我用命令创建了一个“dock

  • 据我所知,docker映像在被拉取时被安装到。有没有办法更改此位置,例如更改到像这样的已安装卷?

  • 今天,我需要一个解决方案来避免在修补程序安装的上下文中通过install4j Version6.1.3创建安装目录。我编写了一个安装程序,其中包含一些文件来将它们安装到现有的应用程序安装中。这些文件应该与修补程序安装程序捆绑在一起。在install files操作中,我停用了install运行时选择点,但安装程序仍然创建了包含名为.install4j的文件夹的安装目录。在这个文件夹中只有一些ins

  • 目前,我发现谷歌云构建发生在构建docker图像的时候(不像我想象的那样,它会构建我的图像,然后执行我的图像来完成所有的构建)。那是在这篇文章里 谷歌云构建的快速启动 我有一个Dockerfile现在很简单 我有一个单一的下载和提取下载任何工件(zip文件)从最后的单构建运行构建(只有修改的服务器被构建或依赖于上一个CI构建的变化的服务器被构建,就像下游库可能被更改)。第一行只是列出了我需要在一个