zhaojun1998

谈一种另类的压缩 Docker 镜像大小的方式

  •  
  •   zhaojun1998 · Dec 24, 2024 · 2106 views
    This topic created in 537 days ago, the information mentioned may be changed or developed.

    最近将一个 Spring Boot 项目编译成了 Spring Native 可执行文件,项目启动速度是上来了,但是可执行文件的大小可骤增至 350M 左右,导致 Docker 镜像的大小也一起增加了很多,考虑到 Docker 拉取本身的网络就很坎坷了,我就想有没有办法能再压缩下大小。

    最开始的方案是使用 upx, 压缩率不错,压缩后可直接执行,但是发现这个工具是有代价的,因为他是执行时从内存中解压你原本的程序,所以你节省了多少可执行文件大小,就会额外占用多少内存,这对我是不可接受的,我觉得内存更可贵一些,这个方案可能更适合 go 程序使用,本身可执行文件大小不会太大,所以也不会导致增加很多内存占用。

    第二个方案是无意中想到的,我能不能自己压缩文件放到镜像中,然后在运行时解压出来再执行,这相较于 upx 的方案来说是在硬盘解压,不会额外占用内存,但是这个要考虑解压的速度(压缩速度不是很重要,可以用 CI/CD 来跑),然后就找到了一个压缩算法 zstd,不论压缩率设置多高,解压缩的时间都是一样的 (如 350M 使用 zstd -19 最高级别,压缩时间 5 分钟,大小可达到 80M 左右,但解压时间仅 0.5 秒)。

    然后在 Dockerfile 中给镜像安装 zstd ,并在最后运行时进行判断是否解压:

    FROM debian:10-slim
    
    ARG TARGETARCH
    
    RUN apt update -y && apt install --no-install-recommends zstd -y && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
    
    # 省略其他
    
    CMD if [ -f /data/app.zst ]; then zstd --no-progress -d /data/app.zst && rm -rf /data/app.zst && chmod +x /data/app && /data/app --spring.config.location=file:/root/application.properties; else chmod +x /data/app && /data/app --spring.config.location=file:/root/application.properties; fi
    

    不知道这种方式算优雅,还是算丑陋,但至少解决了我的问题,希望也能帮助到有类似需求的人。

    5 replies    2024-12-24 18:05:37 +08:00
    mayli
        1
    mayli  
       Dec 24, 2024
    有点闲,docker image 本身就是压缩的

    https://docs.docker.com/build/exporters/#compression

    docker buildx build \
    --output type=image,name=<registry>/<image>,push=true,compression=zstd .
    zhaojun1998
        2
    zhaojun1998  
    OP
       Dec 24, 2024
    @mayli #1

    感谢,我试试这个,之前真不知道。
    netnr
        3
    netnr  
       Dec 24, 2024
    专业的加个参数就搞定了 😂
    pigeon2049
        4
    pigeon2049  
       Dec 24, 2024
    另一个方法
    使用 maven 作为运行时 base image
    或者 dockerfile 里安装 maven
    springboot 使用 thin-launcher

    https://github.com/spring-projects-experimental/spring-boot-thin-launcher

    这样打包时所有依赖都不会带上 配置好 maven 运行时会自动拉取 缺点是首次运行会慢很多
    优点是极度节省 docker 镜像的空间 完整 jar 包 500M
    thin-layout 打出来 5M
    lower
        5
    lower  
       Dec 24, 2024
    @pigeon2049 op 都打成 native image 了,这种应该不支持吧?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   876 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 20:04 · PVG 04:04 · LAX 13:04 · JFK 16:04
    ♥ Do have faith in what you're doing.