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

做了个 Docker image,生成的 image 为什么会这么庞大,附 Dockerfile...

  •  
  •   qazwsxkevin · 10 小时 53 分钟前 · 691 次点击
    ```
    FROM alpine:latest

    # 替换为阿里云的 Alpine 源
    RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories

    # 安装构建和运行所需依赖
    RUN apk add --no-cache \
    build-base \
    ca-certificates \
    tar \
    libressl-dev \
    perl \
    linux-headers \
    musl-dev

    # 将 OpenSSL 源码文件从宿主机复制到容器
    COPY openssl-3.4.0.tar.gz /opt/

    # 解压、编译并安装 OpenSSL
    WORKDIR /opt
    RUN tar -xzf openssl-3.4.0.tar.gz && rm openssl-3.4.0.tar.gz
    WORKDIR /opt/openssl-3.4.0
    RUN ./config no-shared no-zlib no-dso no-tests && \
    make && \
    make install && \
    make clean && \
    rm -rf /opt/openssl-3.4.0

    # 删除构建工具和临时文件
    RUN apk del --purge \
    build-base \
    ca-certificates \
    tar \
    perl \
    linux-headers \
    musl-dev \
    && rm -rf /tmp/* /var/cache/apk/* /usr/share/man /usr/share/doc /usr/share/locale

    # 更新动态链接库路径
    RUN echo "/usr/local/lib64" > /etc/ld-musl-x86_64.path

    # 设置环境变量
    ENV PATH="/usr/local/bin:${PATH}"
    ENV LD_LIBRARY_PATH="/usr/local/lib64:/usr/lib:/lib"

    # 默认命令
    CMD ["openssl", "version"]
    ```

    生成的镜像,有 440MB 之大,是不是有些残留没清干净? 还是 OpenSSL 编译完成,就这么大?
    8 条回复    2024-12-11 23:51:53 +08:00
    Orenoid
        1
    Orenoid  
       10 小时 47 分钟前
    大概率是因为删除构建工具和临时文件这一层,这样是无效的,它只是在这一层把文件标记为删除,要真正删除必须在同一层用 && 执行
    nagisaushio
        2
    nagisaushio  
       10 小时 40 分钟前 via Android
    建议二阶段构建,只拷贝编译完的东西过来
    sagaxu
        3
    sagaxu  
       10 小时 33 分钟前
    docker 的存储是分层的,你每一个 RUN 之后的文件系统都会保留快照,即使最后一个 RUN 是 rm -fr /,中间每一层也都会存储下来占用空间。

    1. 最快的解决方法是把 RUN 全部合并到一个,用&&连接起来。除此之外,以前可以 squash 后来废弃了,现在一般用 multi-stage ,把最终系统复制到一个干净的基准线,中间的 history 就丢弃了,有点儿像 git merge --squash 。

    2. 如果不怕踩坑,也可以试试 podman ,它提供--squash-all 选项构建干净系统。

    3. 最后可以试试 docker export 导出合并后的文件系统,基于这个再重新构建,设置好环境变量。
    ETiV
        4
    ETiV  
       10 小时 18 分钟前 via iPhone
    你要想镜像小就 multi-stage ,在最后一步把需要的东西 copy 出来,中间有多个 RUN 也无妨,还会最大化利用到缓存

    不过纯静态 build 一个可执行程序的话,我一般都单独用它,不会再给它放进 docker image 里…
    Ipsum
        5
    Ipsum  
       10 小时 1 分钟前
    兄弟,你把编译环境一起打包了?应该编译和 bin 分开,编译好了直接 copy 到运行环境中
    Tiller
        6
    Tiller  
       9 小时 5 分钟前
    你运行之后,进去看一下哪些文件比较大就知道了。

    我之前试过一个镜像 1g 多。我都震惊了

    慢慢排查,发现怎么随着版本更新,越来越大了呢?

    从半年前的 200m 渐渐变成 1g 多。

    我对前端的打包流程也不懂,就请教了大佬。他们最后发现,CI/CD 流程出问题了。。。每次打包的临时文件全都放进去了。

    最后每次构建之前删掉临时文件就恢复正常了。
    povsister
        7
    povsister  
       8 小时 48 分钟前
    不用 multi stage 就是一个 run 一层,你数一下你有多少个 run 吧
    wnpllrzodiac
        8
    wnpllrzodiac  
       7 小时 48 分钟前 via Android
    apt 缓存清一下。分 stage,build 后把二进制拷贝到发布 image 最干净
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1139 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 23:40 · PVG 07:40 · LAX 15:40 · JFK 18:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.