V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
rationa1cuzz
V2EX  ›  问与答

请教一些 docker 镜像大小优化问题

  •  
  •   rationa1cuzz · 2021-12-14 16:13:14 +08:00 · 1255 次点击
    这是一个创建于 1054 天前的主题,其中的信息可能已经有所发展或是发生改变。
    前情提要:减少镜像大致分几步,减少层级,多阶段构建(只讨论一般的优化方式),及时删除没必要文件,比如 tar 完及时删除。
    1 、chown 更改拥有者为什么跟 copy 一样大小?
    2 、copy base_package /var/base_package
    run install package
    这种需求有办法优化吗?按照层级意义,第一行 copy 文件大小一直会保存在历史中,及时后面删除了也没用
    3 、我进入系统 du 看了一下 /目录才 800M 实际整个镜像 1.4G 有什么办法变成真实大小,我并不关心层级,只想要个小一点的镜像?
    11 条回复    2021-12-15 10:05:39 +08:00
    startisan
        1
    startisan  
       2021-12-14 16:21:13 +08:00
    直接搞成一层吧
    docker create --name xxx 镜像名
    docker export xxx | docker import - 新镜像名
    ss098
        2
    ss098  
       2021-12-14 16:23:09 +08:00
    第二点问题的解决方案是(不一定是最优解,但我知道可行),在同一条命令中:

    1. 获取数据,比如在容器内从外部 wget 什么的,不要用 COPY 指令
    2. 执行安装
    3. 删除所有不需要的文件
    dolphintwo
        3
    dolphintwo  
       2021-12-14 16:24:15 +08:00
    简单办法:第一个镜像构建,不用在意层数,第二个镜像只拷贝第一个镜像中必要运行环境
    rationa1cuzz
        4
    rationa1cuzz  
    OP
       2021-12-14 16:49:41 +08:00
    @startisan 强啊兄弟
    @ss098 我是离线安装,没办法使用 wget ,有办法不适用 copy 吗?
    @dolphintwo 我不知道哪些是必要环境,装了很多 rpm 包 还要编译同事给源码包,copy --from=build1 / / (这个可以吗)
    Rheinmetal
        5
    Rheinmetal  
       2021-12-14 18:58:25 +08:00
    优化需要更详细的信息
    语言 框架 现有 base image
    一种通用方法是 alpine 做 base image 然后全部静态编译
    某些语言和框架不一定适用 不是 glibc 可能会带来问题

    一个个人前端项目折腾了很多
    用 yarn 做 base image
    仅 copy packages.json npm install 做成 builder 如果依赖不更新这一步直接用缓存
    复制剩下的代码构建
    artifact 放到 alpine 底包的 node 镜像
    做到 总体积十几个 m 更新代码只需 1m 左右 不改依赖用 vite 构建一次几十秒
    arischow
        6
    arischow  
       2021-12-14 19:10:33 +08:00
    多阶段构建用上了吗?用上的话最后的镜像大小应该 == 编译后包大小吧?
    Rheinmetal
        7
    Rheinmetal  
       2021-12-14 19:11:12 +08:00
    为啥要优化镜像大小
    原因决定方向

    为了更新快的话 1L 的一勺烩方案不一定合适
    多层设计就可以做到依赖不动 只更新代码
    底包不动只更新依赖和代码
    noqwerty
        8
    noqwerty  
       2021-12-14 20:41:58 +08:00 via Android
    第一点可以尝试一下 DOCKER_BUILDKIT=1 docker build .,不会生成多余的 intermediate layer
    rationa1cuzz
        9
    rationa1cuzz  
    OP
       2021-12-15 09:20:41 +08:00
    @Rheinmetal 感谢,暂时的需求是做出来的镜像太大,只需要用相对简单一点方法变小就行,后面如果有更多需求可以按你这个来。
    @arischow 还没,因为我菜,加上包有离线 rpm 包,有 glibc ,所以一时间不知道怎么写--from 参数
    @noqwerty 感谢,我试试
    @startisan 老哥你这有坑啊,export 是根据 container 生成的,会丢失 docker file 中的 run 命令,需要注意
    Rheinmetal
        10
    Rheinmetal  
       2021-12-15 09:29:30 +08:00
    @Rheinmetal
    glibc 的话 是不是直接静态编译?
    rationa1cuzz
        11
    rationa1cuzz  
    OP
       2021-12-15 10:05:39 +08:00
    @Rheinmetal 没有默认的应该是动态编译,没加-static
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2854 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 14:26 · PVG 22:26 · LAX 07:26 · JFK 10:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.