能否合并已构建完成的两个Docker镜像?
合并已构建的Alpine Docker镜像
场景说明
- 已构建完成镜像A:基于Alpine系统,内置
task命令 - 已构建完成镜像B:基于Alpine系统,内置
fzf命令 - 已知可通过多阶段构建生成包含两个命令的镜像,但希望直接合并已有的镜像文件,尝试
docker-merge工具时出现报错,寻求可行方案
方案1:复用已有镜像的多阶段构建
不用重新安装软件,直接把已有的镜像作为多阶段构建的基础,复制需要的文件即可,这是最稳妥的方式:
# 引入已有的镜像A作为阶段镜像 FROM 镜像A的名称/镜像ID as stage-task # 引入已有的镜像B作为最终镜像的基础 FROM 镜像B的名称/镜像ID as final # 从stage-task复制task命令到最终镜像 COPY --from=stage-task /usr/bin/task /usr/bin/task # (可选)如果task有依赖库,先在镜像A中用`ldd /usr/bin/task`查看依赖路径,再复制对应文件 # 例如:COPY --from=stage-task /usr/lib/libfoo.so.1 /usr/lib/ # 保留原镜像的CMD或自定义 CMD ash
注:如果两个镜像基于同版本Alpine,直接复制二进制文件基本就能正常运行;版本不同的话需要额外处理依赖库。
方案2:手动导出文件系统后合并
如果不想写Dockerfile,可以手动导出两个镜像的文件系统,合并后重新导入为新镜像:
- 启动临时容器以便导出文件系统:
docker run -d --name tempA 镜像A的名称/镜像ID sleep infinity docker run -d --name tempB 镜像B的名称/镜像ID sleep infinity - 导出两个容器的文件系统为tar包:
docker export tempA > a.tar docker export tempB > b.tar - 创建临时目录,解压并合并两个文件系统:
mkdir -p merged_fs # 先解压镜像A的文件 tar -xf a.tar -C merged_fs # 解压镜像B的文件,--keep-old-files避免覆盖已有文件(比如系统基础文件) tar -xf b.tar -C merged_fs --keep-old-files - 将合并后的文件系统导入为新镜像:
tar -cf merged.tar -C merged_fs . docker import merged.tar alpine-task-fzf:latest - 清理临时资源:
rm -rf merged_fs a.tar b.tar merged.tar docker rm -f tempA tempB
注:这种方式生成的镜像没有原镜像的元数据(比如环境变量、默认CMD等),可以用
docker commit添加,或者基于该镜像写个简单的Dockerfile补充。
关于docker-merge报错的说明
docker-merge对镜像层的兼容性要求较高,Alpine镜像的分层结构比较精简,容易出现层不匹配的问题,因此不推荐使用。上述两种方案更适合Alpine镜像的合并场景。
内容的提问来源于stack exchange,提问作者StevieD
相关产品推荐
相关产品推荐

