Docker 镜像多阶段构建实战总结
文章目录
- Docker 镜像多阶段构建实战总结
- 一 背景
- 二 实践步骤
- 2.1 只通过一个 Dockerfile 来构建【方案一】
- 2.2 多个 Dockerfile 实现多阶段构建【方案二】
- 2.3 一个 Dockerfile 实现多阶段构建【方案三】
- 三 总结
- 四 参考文档
Docker 镜像多阶段构建实战总结
一 背景
通常情况下,构建镜像通常会采用两种方式:
- 将全部组件及其依赖库的编译、测试、打包等流程封装进一个 Docker 镜像中。采用这种方式往往忽略了以下这些问题:
- Dockefile 特别长,可维护性降低。
- 镜像的层次多,体积大,部署时间长。
- 源代码存在泄漏的风险。
- 分散到多个 Dockerfile。事先在一个 Dockerfile 将项目及其依赖库编译测试打包好后,再将其拷贝到运行环境中,这种方式需要我们编写两个 Dockerfile 和一些编译脚本才能将其两个阶段自动整合起来,这种方式虽然可以很好地规避第一种方式存在的风险,但明显部署过程较复杂。
为了解决以上这些问题,Docker v17.05 开始支持多镜像阶段构建 (multistage builds)。只需要编写一个 Dockerfile 即可。通过一段简单的 C 语言代码的编译、执行来具体演示。demo.c 的内容如下:
# include<stdio.h>
int main()
{printf("%s\n","This is a demo!");return 0;
}
二 实践步骤
2.1 只通过一个 Dockerfile 来构建【方案一】
查看对应的 Dockerfile:
FROM centos:7.8.2003ENV VERSION 1.0WORKDIR /demoCOPY demo.c .RUN yum install -y gcc && \gcc -v
RUN gcc demo.c -o demo && \rm -f demo.c && \yum erase -y gcc && \cp demo /usr/local/bin/CMD ["demo"]
感兴趣的小伙伴可以直接将上面的 Dockerfile 和 docker-entrypoint.sh 在本地构建目录创建,执行 docker build -t redis:6.0.5-buster
进行尝试。
2.2 多个 Dockerfile 实现多阶段构建【方案二】
多阶段构建一般需要多个 Dockerfile 来完成,由于我们只需要源码编译后的产物。所以我们第一个阶段可以直接使用上文中镜像构建后的产物。第二阶段的 Dockerfile 内容如下:
FROM centos:7.8.2003ENV VERSION 1.0WORKDIR /demoCOPY demo /usr/local/binCMD ["demo"]
执行构建脚本 bash build.sh
, build.sh
的内容如下:
#!/bin/bash
cd stage-1
docker create --name bin demo:1.0
cd ../stage-2
docker cp bin:/usr/local/bin/demo .
docker rm -f bin
docker build -t demo:2.0 .
构建后得到的 Docker 容器运行结果:
$ docker run --rm -it demo:1.0
This is a demo!
$ docker run --rm -it demo:2.0
This is a demo!
两个容器的环境变量:
$ docker run --rm -it demo:1.0 env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=a52af1bec0af
TERM=xterm
VERSION=1.0
HOME=/root
$ docker run --rm -it demo:2.0 env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=f6618fd1244b
TERM=xterm
VERSION=2.0
HOME=/root
2.3 一个 Dockerfile 实现多阶段构建【方案三】
FROM centos:7.8.2003ENV VERSION 1.0WORKDIR /demoCOPY demo.c .RUN yum install -y gcc && \gcc -v
RUN gcc demo.c -o demo && \rm -f demo.c && \yum erase -y gcc && \cp demo /usr/local/bin/FROM centos:7.8.2003
COPY --from=0 /usr/local/bin/demo /usr/local/bin/demoCMD ["demo"]
这种方式构建的 Docker 容器运行结果:
$ docker run --rm -it demo:3.0
This is a demo!
$ docker run --rm -it demo:3.0 env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=7839b3d568db
TERM=xterm
HOME=/root
三个镜像大小对比:
$ docker images|grep demo
demo 3.0 8766031d380a 39 seconds ago 203MB
demo 2.0 7d9c479cb421 10 minutes ago 203MB
demo 1.0 af331209572f 38 minutes ago 350MB
三 总结
- 3.1 通过观察,方案一构建得到镜像远比方案二和方案三大得多,方案二和方案三的镜像一样大小。
- 3.2 方案三并不会继承第一阶段构建的镜像的环境变量等配置,仅仅是复制了第一阶段的构建成果,需要特别注意。
四 参考文档
- 4.1 官方文档-快速开始
- 4.2 Docker Hub官方镜像
- 4.3 GitHub 官方仓库
- 4.4 10 Docker Security Best Practices
- 4.5 Best practices for writing Dockerfiles
Docker 镜像多阶段构建实战总结相关推荐
- 构建Docker镜像指南,含实战案例
[Docker那些事]系列文章 Dockerfile 文件结构.docker镜像构建过程详细介绍 Dockerfile文件中CMD指令与ENTRYPOINT指令的区别 构建Docker镜像指南,含实战 ...
- 线上Go项目的Docker镜像应该怎么构建?
上期的文章:Kubernetes入门实践--部署运行Go项目发布后,有网友留言说我文章里演示的镜像是把项目文件和Go都打包到了镜像里,这样镜像的占用空间会比较大. Go开发的程序在编译成二进制文件后是 ...
- Docker最全总结,DockerFile,Docker编排容器,Docker镜像,Docker-compose构建
文章目录 Docker 简介 为什么使用docker: Docker引擎: Docker系统镜像: Docker容器: Docker仓库: ubuntu安装docker: ubuntu脚本自动安装: ...
- Docker镜像的三大构建方式
摘要 在构建容器化应用时,相当重要的步骤莫过于镜像制作,本文将介绍镜像制作方法以及镜像制作的建议. 采用docker commit生成的镜像实际上是容器内的文件系统进行修改在进行提交,而运行的容器实际 ...
- Spring Boot 2.3.x 分层构建 Docker 镜像实战
目录 一.什么是镜像分层 二.SpringBoot 2.3.x 新增对分层的支持 三.创建测试的 SpringBoot 应用 1.Maven 中引入相关依赖和插件 2.创建测试的 Controller ...
- Spring Boot 分层构建 Docker 镜像实战
目录 一.什么是镜像分层 二.SpringBoot 2.3.x 新增对分层的支持 三.创建测试的 SpringBoot 应用 1.Maven 中引入相关依赖和插件 2.创建测试的 Controller ...
- SpringBoot 2.3.x 分层构建 Docker 镜像实践
目录[-] . 一.什么是镜像分层 . 二.SpringBoot 2.3.x 新增对分层的支持 . 三.创建测试的 SpringBoot 应用 . 1.Maven 中引入相关依赖和插件 . 2.创建测 ...
- 基于领域知识的Docker镜像自动构建方法
点击上方蓝字关注我们 基于领域知识的Docker镜像自动构建方法 陈伟1,2, 叶宏杰1,2, 周家宏1,2, 魏峻1,2 1 中国科学院大学,北京 100190 2 中国科学院软件研究所,北京 10 ...
- Dockerfile 文件结构、docker镜像构建过程详细介绍
[Docker那些事]系列文章 Dockerfile 文件结构.docker镜像构建过程详细介绍 Dockerfile文件中CMD指令与ENTRYPOINT指令的区别 构建Docker镜像指南,含实战 ...
最新文章
- 机器学习基础-弹性网 Elastic Net-08
- 基站定位php,SIM800C支持基站定位功能了。。。
- android wifi视频监控软件,WiFi环境下Android智能视频监控系统研究与实现
- Django框架 from django.core.files.uploadedfile import InMemoryUploadedFile
- 产品泛滥的时代,如何让你的产品脱颖而出?
- i5700 预,链接
- SQL查询最近几年、几月的数据
- e-HR推动知识型企业人力资源管理提升
- Go 依赖管理工具 Dep 的安装及配置
- 什么时候可以重用我~
- 三维坐标要建一个4*4的矩阵?
- Welearn的cookie值怎么获取?
- (Demo分享)利用JavaScript(JS)做一个可输入分钟的倒计时钟功能
- java里getter和setter的作用和区别是什么?
- PPT的那些事儿(趣资源)
- [CTF]ACSII码
- java.io.FileNotFoundException: D:\hadoop (拒绝访问。)
- 淘宝开发平台店铺商品上传接口,店铺订单交易接口,店铺订单解密接口,店铺上下架接口,店铺订单推送接口(整理好的完整店铺上货订单操作接口)
- Mac软件爆品返场 优惠依旧给力
- 静态成员、this指针
热门文章
- 初学者学习编程,如何训练自己的编程思维,资深程序员这样建议
- 最简单的GB28181视频PS流播放器。
- 如何将excel的一列变成多列(多排表使用帮助)
- ODBC中用户DSN、系统DSN、文件DSN各代表的含义
- error C4996: ‘GetVersionExA‘: 被声明为已否决
- 深入理解Java虚拟机-走近Java
- win server 2012 R2 你需要先安装 对应于 KB2919355 的更新 ,然后才可在 Windows 8.1 或 Windows Server 2012 R2 上安装此产品。
- 如何为安卓程序设置启动页面(splash)?
- 【BDTC 2016】与360、安天、三未信安、明朝万达、数字观星、观数科技共同讨论大数据安全与隐私保护...
- OSATs basic information