优化 docker 镜像构建时需要重复下载 apk
众所周知,如果我们需要在 docker 镜像构建时通过包管理器下载一些软件,那么每次我们在修改 DockerFile 时,都需要重新下载一遍,这样会导致构建时间变长,而且如果我们的网络不是很好,那么下载的过程中还可能会出现失败的情况,这样就会导致构建失败,所以我们需要优化这个过程。
环境
- 宿主机: 20.04.6 LTS (Focal Fossa)
- docker: Docker version 24.0.4, build 3713ee1
- docker-compose: docker-compose version 1.27.4, build 40524192
- alpine: 3.11.6
示例
在这个 DockerFile 中,我们需要编译 nginx,所以有以下这行命令被执行:
1 | # ... |
每次在构建镜像时都会重新下载这些包 gcc libc-dev make openssl-dev pcre-dev zlib-dev linux-headers
,每次只要修改的内容在这行命令之前都会重新触发下载,这将大大增加构建时间,也白白浪费带宽。
优化思路
办法很简单,就是将这些包保存到本地,在构建时在使用已经下载完成的包进行安装,整过构建流程就会被加快
获取 apk 包
这里以
gcc libc-dev make openssl-dev pcre-dev zlib-dev linux-headers
为例
进入 alpine 镜像
1
docker run -it alpine:3.11.6 /bin/sh
将包下载到本地
1
2
3
4# 设置镜像源
sed -i "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g" /etc/apk/repositories
# 下载包
apk fetch --recursive --no-cache gcc libc-dev make openssl-dev pcre-dev zlib-dev linux-headers -o /tmp下载后的 apk 文件会保存在
/tmp
目录下将包复制到宿主机
1
docker cp <containerId>:/tmp /host/path/apk
使用本地 apk 包
修改 DockerFile
1
2
3
4
5# ...
COPY /host/path/apk /tmp # 将本地的 apk 复制到镜像中
RUN apk add --no-cache --virtual dependency /tmp/*.apk \ # 使用本地的 apk 进行安装
# ...构建镜像
1
docker build -t nginx:alpine .
到这里,我们就可以发现构建速度已经有了较大的提升
后记
总结一下优缺点:
优点
- 构建速度提升
- 避免了因为网络问题而导致构建失败
- 足够灵活,如果我们不需要某个包或需要临时增加某个包,只需要修改本地的 apk 包即可
缺点
- 需要手动下载 apk 包,并复制到镜像中
- 需要匹配包的版本和镜像的版本,否则可能会出现不兼容的情况,当然这种情况只需要重新下载即可
当然,不仅仅只有这一种方式,还有其他的方式,比如通过创建一个已经安装好这些包的基础镜像,再通过这个基础镜像进行后续编译,但是这种方式的弊端也比较明显,不够灵活,所以我个人还是更喜欢上面这种方式。
- 标题: 优化 docker 镜像构建时需要重复下载 apk
- 作者: CListery
- 创建于 : 2023-10-07 10:14:18
- 更新于 : 2024-11-15 15:53:32
- 链接: http://clistery.github.io/2023/10/07/docker/apline-apk-locally/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论