文章目录

  • Docker 镜像多阶段构建实战总结
    • 一 背景
    • 二 实践步骤
      • 2.1 只通过一个 Dockerfile 来构建【方案一】
      • 2.2 多个 Dockerfile 实现多阶段构建【方案二】
      • 2.3 一个 Dockerfile 实现多阶段构建【方案三】
    • 三 总结
    • 四 参考文档

Docker 镜像多阶段构建实战总结

一 背景

通常情况下,构建镜像通常会采用两种方式:

  1. 将全部组件及其依赖库的编译、测试、打包等流程封装进一个 Docker 镜像中。采用这种方式往往忽略了以下这些问题:

    • Dockefile 特别长,可维护性降低。
    • 镜像的层次多,体积大,部署时间长。
    • 源代码存在泄漏的风险。
  2. 分散到多个 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 镜像多阶段构建实战总结相关推荐

  1. 构建Docker镜像指南,含实战案例

    [Docker那些事]系列文章 Dockerfile 文件结构.docker镜像构建过程详细介绍 Dockerfile文件中CMD指令与ENTRYPOINT指令的区别 构建Docker镜像指南,含实战 ...

  2. 线上Go项目的Docker镜像应该怎么构建?

    上期的文章:Kubernetes入门实践--部署运行Go项目发布后,有网友留言说我文章里演示的镜像是把项目文件和Go都打包到了镜像里,这样镜像的占用空间会比较大. Go开发的程序在编译成二进制文件后是 ...

  3. Docker最全总结,DockerFile,Docker编排容器,Docker镜像,Docker-compose构建

    文章目录 Docker 简介 为什么使用docker: Docker引擎: Docker系统镜像: Docker容器: Docker仓库: ubuntu安装docker: ubuntu脚本自动安装: ...

  4. Docker镜像的三大构建方式

    摘要 在构建容器化应用时,相当重要的步骤莫过于镜像制作,本文将介绍镜像制作方法以及镜像制作的建议. 采用docker commit生成的镜像实际上是容器内的文件系统进行修改在进行提交,而运行的容器实际 ...

  5. Spring Boot 2.3.x 分层构建 Docker 镜像实战

    目录 一.什么是镜像分层 二.SpringBoot 2.3.x 新增对分层的支持 三.创建测试的 SpringBoot 应用 1.Maven 中引入相关依赖和插件 2.创建测试的 Controller ...

  6. Spring Boot 分层构建 Docker 镜像实战

    目录 一.什么是镜像分层 二.SpringBoot 2.3.x 新增对分层的支持 三.创建测试的 SpringBoot 应用 1.Maven 中引入相关依赖和插件 2.创建测试的 Controller ...

  7. SpringBoot 2.3.x 分层构建 Docker 镜像实践

    目录[-] . 一.什么是镜像分层 . 二.SpringBoot 2.3.x 新增对分层的支持 . 三.创建测试的 SpringBoot 应用 . 1.Maven 中引入相关依赖和插件 . 2.创建测 ...

  8. 基于领域知识的Docker镜像自动构建方法

    点击上方蓝字关注我们 基于领域知识的Docker镜像自动构建方法 陈伟1,2, 叶宏杰1,2, 周家宏1,2, 魏峻1,2 1 中国科学院大学,北京 100190 2 中国科学院软件研究所,北京 10 ...

  9. Dockerfile 文件结构、docker镜像构建过程详细介绍

    [Docker那些事]系列文章 Dockerfile 文件结构.docker镜像构建过程详细介绍 Dockerfile文件中CMD指令与ENTRYPOINT指令的区别 构建Docker镜像指南,含实战 ...

最新文章

  1. 机器学习基础-弹性网 Elastic Net-08
  2. 基站定位php,SIM800C支持基站定位功能了。。。
  3. android wifi视频监控软件,WiFi环境下Android智能视频监控系统研究与实现
  4. Django框架 from django.core.files.uploadedfile import InMemoryUploadedFile
  5. 产品泛滥的时代,如何让你的产品脱颖而出?
  6. i5700 预,链接
  7. SQL查询最近几年、几月的数据
  8. e-HR推动知识型企业人力资源管理提升
  9. Go 依赖管理工具 Dep 的安装及配置
  10. 什么时候可以重用我~
  11. 三维坐标要建一个4*4的矩阵?
  12. Welearn的cookie值怎么获取?
  13. (Demo分享)利用JavaScript(JS)做一个可输入分钟的倒计时钟功能
  14. java里getter和setter的作用和区别是什么?
  15. PPT的那些事儿(趣资源)
  16. [CTF]ACSII码
  17. java.io.FileNotFoundException: D:\hadoop (拒绝访问。)
  18. 淘宝开发平台店铺商品上传接口,店铺订单交易接口,店铺订单解密接口,店铺上下架接口,店铺订单推送接口(整理好的完整店铺上货订单操作接口)
  19. Mac软件爆品返场 优惠依旧给力
  20. 静态成员、this指针

热门文章

  1. 初学者学习编程,如何训练自己的编程思维,资深程序员这样建议
  2. 最简单的GB28181视频PS流播放器。
  3. 如何将excel的一列变成多列(多排表使用帮助)
  4. ODBC中用户DSN、系统DSN、文件DSN各代表的含义
  5. error C4996: ‘GetVersionExA‘: 被声明为已否决
  6. 深入理解Java虚拟机-走近Java
  7. win server 2012 R2 你需要先安装 对应于 KB2919355 的更新 ,然后才可在 Windows 8.1 或 Windows Server 2012 R2 上安装此产品。
  8. 如何为安卓程序设置启动页面(splash)?
  9. 【BDTC 2016】与360、安天、三未信安、明朝万达、数字观星、观数科技共同讨论大数据安全与隐私保护...
  10. OSATs basic information