You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅保留Docker中RUN编译步骤生成的修改文件至新镜像层?

解决Docker编译后仅保留构建产物的方案

针对源码编译后无法精准定位产物目录、镜像体积过大的问题,有两种实用的实现方式:

方案一:基于文件系统快照对比的多阶段构建

通过在编译前后生成文件系统快照,对比出新增/修改的文件,再按需复制到运行时镜像:

# 构建层:完成源码编译并记录文件变化
FROM ubuntu as build-layer

# 安装编译依赖(按需调整)
RUN apt-get update && apt-get install -y git build-essential tar diffutils

# 1. 克隆源码到指定目录
RUN git clone <你的源码仓库地址> /src

# 2. 创建编译前的文件系统基准快照(排除系统临时目录和源码目录)
RUN tar -cf /pre-build.tar --exclude=/proc --exclude=/sys --exclude=/dev --exclude=/src /

# 3. 执行编译及安装
RUN cd /src && make && make install

# 4. 生成编译后快照,对比找出所有新增/修改的文件并保存列表
RUN tar -cf /post-build.tar --exclude=/proc --exclude=/sys --exclude=/dev --exclude=/src / && \
    diff -u <(tar -tf /pre-build.tar | sort) <(tar -tf /post-build.tar | sort) | grep '^+' | cut -c2- > /changed-files.txt

# 运行时层:仅复制编译产生的变化文件
FROM ubuntu as runtime-layer

# 复制文件列表并批量复制对应文件
COPY --from=build-layer /changed-files.txt /tmp/
RUN xargs -a /tmp/changed-files.txt -I {} mkdir -p $(dirname {}) && \
    xargs -a /tmp/changed-files.txt -I {} cp --parents {} /

方案二:使用Docker Buildkit的临时挂载隔离源码

将源码克隆到临时挂载目录(构建后自动清理,不会进入镜像层),直接提取编译产物:

# 启用Buildkit(构建时需加环境变量:DOCKER_BUILDKIT=1)
# syntax=docker/dockerfile:1.4

FROM ubuntu as build-layer

RUN apt-get update && apt-get install -y git build-essential

# 挂载临时目录存储源码,构建完成后该目录自动销毁
RUN --mount=type=tmpfs,target=/src \
    git clone <你的源码仓库地址> /src && \
    cd /src && make && make install

# 运行时层:复制构建层的系统文件(因源码在tmpfs,仅包含编译产物)
FROM ubuntu as runtime-layer
COPY --from=build-layer / /

关键说明

  • 方案一的快照对比法精度更高,能严格只保留编译产生的文件,适合需要精准控制镜像内容的场景,但需注意排除系统无关目录
  • 方案二操作更简洁,利用Buildkit特性避免源码占用镜像空间,适合基础镜像干净、编译过程无冗余操作的场景
  • 若编译过程涉及文件删除,可调整方案一的diff逻辑,补充捕获删除的文件(实际场景中一般无需处理,运行时镜像基于干净的基础镜像)

内容的提问来源于stack exchange,提问作者FabianTe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:42:21