我的Dockerfile类似于
FROM my/base
ADD . /srv
RUN pip install -r requirements.txt
RUN python setup.py install
ENTRYPOINT ["run_server"]
字符串
每次我构建一个新的映像,都必须重新安装依赖项,这在我的地区可能非常慢。
我想到的一种方法是用新的镜像覆盖my/base
镜像,如下所示:
docker build -t new_image_1 .
docker tag new_image_1 my/base
型
所以下次我用这个Dockerfile构建时,我的/base已经安装了一些包。
但这种解决方案有两个问题:
1.并不总是可以覆盖基础映像
1.随着新图像的叠加,基础图像会变得越来越大
那么,有什么更好的方法可以解决这个问题呢?
编辑:
关于我机器上的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
型
6条答案
按热度按时间3qpi33ja1#
尝试构建一个Dockerfile,它看起来像这样:
字符串
Docker将在pip安装期间使用缓存,只要您不对
requirements.txt
进行任何更改,无论.
中的其他代码文件是否更改。举个例子下面是一个简单的
Hello, World!
程序:型
docker build的输出:
型
让我们修改
run.py
:型
尝试再次构建,下面是输出:
型
正如你在上面看到的,这次docker在构建过程中使用了cache。现在,让我们更新
requirements.txt
:型
下面是docker build的输出:
型
注意docker在pip安装过程中没有使用cache。如果不起作用,请检查您的docker版本。
型
jtw3ybtb2#
我知道这个问题已经有了一些流行的答案。但是有一种更新的方法可以为包管理器缓存文件。我认为,在将来BuildKit变得更加标准时,这可能是一个很好的答案。
从Docker 18.09开始,对BuildKit有实验性的支持。BuildKit在Dockerfile中增加了对一些新特性的支持,包括对将外部卷装入
RUN
步骤的实验性支持。这允许我们为$HOME/.cache/pip/
这样的东西创建缓存。我们将使用下面的
requirements.txt
文件作为示例:字符串
Python
Dockerfile
的典型示例如下所示:型
在使用
DOCKER_BUILDKIT
环境变量启用BuildKit的情况下,我们可以在大约65秒内构建未缓存的pip
步骤:型
现在,让我们添加实验性的头文件,并修改
RUN
步骤来缓存Python包:型
现在继续进行另一个构建。应该需要相同的时间。但这一次,它将Python包缓存在我们的新缓存挂载中:
型
大约60秒。与我们的第一个构建类似。
对
requirements.txt
做一个小的更改(例如在两个包之间添加一个新行),强制缓存无效并再次运行:型
只有十六秒左右!
我们之所以能获得这样的加速,是因为我们不再下载所有的Python包。它们由包管理器(在本例中为
pip
)缓存并存储在缓存卷挂载中。为run步骤提供了卷挂载,以便pip
可以重用已经下载的包。这发生在任何Docker层缓存之外。在更大的
requirements.txt
上,增益应该会更好。备注:
docker system prune -a
时,它会被清除。希望这些特性能够进入Docker进行构建,BuildKit将成为默认的。如果/当这种情况发生时,我会尝试更新这个答案。
nkhmeac63#
为了最小化网络活动,可以将
pip
指向主机上的缓存目录。运行你的docker容器,将你的主机的pip缓存目录绑定挂载到你的容器的pip缓存目录中。
docker run
命令应该如下所示:字符串
然后在你的Dockerfile中将你的需求作为
ENTRYPOINT
语句(或CMD
语句)的一部分安装,而不是作为RUN
命令。这一点很重要,因为(正如注解中指出的那样)在映像构建期间(当执行RUN
语句时),挂载不可用。Docker文件应该看起来像这样:型
t1rydlwq4#
字符串
默认情况下尝试重新锁定。当它这样做时,Docker构建的缓存层不会被使用,因为Pipfile.lock已经更改。见文档
解决这个问题的一个方法是对Pipfile.lock进行版本控制,并使用
型
而是
感谢JFG Piñeiro。
wwwo4jvm5#
当你尝试使用GitLab CI/CD来实现这一点时,你可以遵循这个文档:https://docs.gitlab.com/ee/ci/docker/docker_layer_caching.html
如果它对您不起作用,请尝试显式设置
DOCKER_BUILDKIT
和BUILDKIT_INLINE_CACHE
字符串
wmvff8tz6#
我发现更好的方法是将Python站点包目录添加为卷。
字符串
这样我就可以pip安装新的库,而不必做一个完整的重建。
编辑:忽略这个答案,jkukul的上面的答案对我有用。我的目的是缓存site-packages文件夹。看起来更像是:
型
缓存下载文件夹是很多清洁虽然。这也缓存了轮子,所以它正确地完成了任务。