当前位置: 首页 > backend >正文

docker多阶段构建镜像

       工作中常常用到docker,现在有这样一个场景:已经有一个打好的docker镜像A,主要是包含系统文件(1-3G)、pyhton env(9-10G)文件、模型权重文件modelA(65G)和python代码文件。同时重新安装pyhton env耗时很久(安装torch/cuda/sglang)等等。现在要把modelA切换为modelB(也是65G),要快速的构建好docker image B,同时又要保证docker image B的体积尽可能的小。那么这个dockerfile该怎么写呢?

        为了构建的时间最小,因此python env 不要再次安装(这个一般需要2-3个小时,也假设之前构建docker镜像A的时候 pip 没有缓存),那么就得依赖docker镜像A;为了最终构建镜像体积小,所以要不镜像A中的模型权重文件modelA给删除掉。按照这个思路貌似就很容易完成这个任务。

FROM imageA
RUN rm -rf /app/*.py
RUN rm -rf /app/modelACOPY models/modelB modelB 
ENV PATH="/app:$PATH"
COPY config.toml .
COPY *.py .
RUN python3 -m pip install pytomlpp -i https://pypi.tuna.tsinghua.edu.cn/simple
CMD ["python", "llm_sglang_server_ws.py"]

最后运行docker build -t  imageB -f ./Dockerfile . 构建新的镜像,最后发现imageB的体积比imageA要大65G,貌似RUN rm -rf /app/modelA 并没有生效一样。这是因为docker镜像的存储是按照layer来进行的,dockerfile中每一条命令FROM、COPY、RUN、CMD等都会产生一个layer,每一层layer都是基于之前的所有layer来进行构建的。docker镜像的大小就是所有layer的大小之和。具体都上面的dockerfile中,RUN rm -rf /app/modelA 这个命令指示标记删除modelA在最后的镜像中不可见,但是modelA仍然存在某些layer中

FROM imageA                                                                                                          75G
RUN rm -rf /app/*.py                                                                                                 0B
RUN rm -rf /app/modelA                                                                                           0B

COPY models/modelB modelB                                                                                 65G
ENV PATH="/app:$PATH"                                                                                        0B
COPY config.toml .                                                                                                   1kB
COPY *.py .                                                                                                               80kB
RUN python3 -m pip install pytomlpp -i https://pypi.tuna.tsinghua.edu.cn/simple     13MB
CMD ["python", "llm_sglang_server_ws.py"]                                                              0B

因此总计 65G+75G = 140G

因此我们就需要采用多阶段来构建,多阶段就是使用多个FROM命令,有个特点就是镜像只会保留最后一个FROM后面的非FROM命令的层。先把dockerfile多阶段构建的给出来

FROM imageA as builder
RUN rm -rf /app/*.py
RUN rm -rf /app/modelAFROM scratch
WORKDIR /app
COPY --from=builder / /
COPY models/modelB modelBARG docker_dir="docker"
ENV PATH="/app:$PATH"
COPY config.toml .
COPY *.py .
RUN python3 -m pip install pytomlpp -i https://pypi.tuna.tsinghua.edu.cn/simple
CMD ["python", "llm_sglang_server_ws.py"]

分析一下这个dockerfile以及构建后的镜像

首先FROM scratch引入了一个空镜像,不占空间;COPY --from=builder / / 从第一阶段的镜像中把/路径下的文件全部复制过来了(包含各种系统文件、python env等),docker history Image 看看构建后的镜像:

镜像总计9层,每层的大小也具体显示出来了,符合我们上述的分析——只有最后一个FROM后的命令对应的layer保留下来了。

以上内容仅仅是对当前场景怎么快速构建一个体积相对较小同时有满足需求的镜像,给出了演示和分析。关于docker镜像的压缩和精简,在构建的时候还有其他的一些技巧,合并多个同类命令为一个命令、清除缓存、使用轻量化的基础镜像等,这里我们就不做过多的学习了。

http://www.xdnf.cn/news/8176.html

相关文章:

  • gd32e230c8t6 驱动ws2812
  • 几种直流电流采样方法
  • ADC 单次转换、连续转换、扫描转换和间接转换模式 详解。
  • MySQL 可观测性最佳实践
  • 怎样通过神经网络估计股票走向
  • Jeecg漏洞总结及tscan poc分享
  • 现代健康养生指南
  • 性能测试场景题
  • 高频晶振的信号完整性挑战:如何抑制EMI与串扰
  • 如何在 Windows 11/10 计算机上有效粉碎文件
  • 十二、Linux实现截屏小工具
  • [MH22D3开发笔记]1. 变量地址对齐,宏__ALIGNED的使用
  • MRI学习笔记-表征相似性分析(Representational Similarity Analysis, RSA)
  • Redis 中如何保证缓存与数据库的数据一致性?
  • 高性能算法RIME:基于物理的优化的霜冰优化算法
  • Golang——1、环境搭建与入门
  • 苍穹外卖06 HttpClient微信小程序开发 微信登录导入商品浏览功能代码
  • Vue3前后端分离用户信息显示方案
  • ModbusRTU转profibusDP网关接皖仪SFJ-16M 氦质谱检漏仪与PLC通讯
  • 虚拟小号查询技术解析
  • Redis进阶之高可用
  • 选新手机的参考:CPU型号、内存、外存、屏幕、摄像头以及电池等。
  • 详解受约束的强化学习(三、公式关系串联)
  • 【Linux 服务器磁盘映像备份与恢复实战指南】虚拟机备份,物理机上云都可以用这套方案!
  • 2025年气候持续大风,消纳减少,如何保收益?东润能源整体解决方案持续保收益保增长
  • C++:面试题汇总
  • 系统与账户安全
  • 一个纯粹基于jQuery和Django的SSE站内信通知的例子
  • 飞牛fnNAS远程映射盘符
  • PARSCALE:大语言模型的第三种扩展范式