Docker学习——多阶段构建(六)
之前的做法
在 Docker 17.05 版本之前,我们构建 Docker 镜像时,通常会采用两种方式:
全部放入一个 Dockerfile
一种方式是将所有的构建过程编包含在一个 Dockerfile 中,包括项目及其依赖库的编译、
测试、打包等流程,这里可能会带来的一些问题:
1、Dockerfile 特别长,可维护性降低
2、镜像层次多,镜像体积较大,部署时间变长
3、源代码存在泄露的风险
例如
编写 app.go 文件,该程序输出 Hello World!
package main
import "fmt"
func main(){
fmt.Printf("Hello World!");
}
编写 Dockerfile.one 文件
FROM golang:1.9-alpine
RUN apk --no-cache add git ca-certificates
WORKDIR /go/src/github.com/go/helloworld/
COPY app.go .
RUN go get -d -v github.com/go-sql-driver/mysql \
&& CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . \
&& cp /go/src/github.com/go/helloworld/app /root
WORKDIR /root/
CMD ["./app"]
构建镜像
$ docker build -t go/helloworld:1 -f Dockerfile.one . 分散到多个 Dockerfile
另一种方式,就是我们事先在一个 Dockerfile 将项目及其依赖库编译测试打包好后,再将其拷贝到运行环境中,这种方式需要我们编写两个 Dockerfile 和一些编译脚本才能将其两个阶段自动整合起来,这种方式虽然可以很好地规避第一种方式存在的风险,但明显部署过程较复杂。
例如
编写 Dockerfile.build 文件
FROM golang:1.9-alpine
RUN apk --no-cache add git
WORKDIR /go/src/github.com/go/helloworld
COPY app.go .
RUN go get -d -v github.com/go-sql-driver/mysql \
&& CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . 编写 Dockerfile.copy 文件
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY app .
CMD ["./app"]
新建 build.sh
#!/bin/sh
echo Building go/helloworld:build
docker build -t go/helloworld:build . -f Dockerfile.build
docker create --name extract go/helloworld:build
docker cp extract:/go/src/github.com/go/helloworld/app ./app
docker rm -f extract
echo Building go/helloworld:2
docker build --no-cache -t go/helloworld:2 . -f Dockerfile.copy
rm ./app
现在运行脚本即可构建镜像
$ chmod +x build.sh
$ ./build.sh
对比两种方式生成的镜像大小
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
go/helloworld 2 f7cf3465432c 22 seconds ago 6.47MB
go/helloworld 1 f55d3e16affc 2 minutes ago 295MB
使用多阶段构建
为解决以上问题,Docker v17.05 开始支持多阶段构建 ( multistage builds )。使用多阶段构建我们就可以很容易解决前面提到的问题,并且只需要编写一个 Dockerfile :
例如 编写 Dockerfile 文件
FROM golang:1.9-alpine as builder
RUN apk --no-cache add git
WORKDIR /go/src/github.com/go/helloworld/
RUN go get -d -v github.com/go-sql-driver/mysql
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest as prod
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/go/helloworld/app .
CMD ["./app"]
构建镜像
$ docker build -t go/helloworld:3 .
对比三个镜像大小
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
go/helloworld 3 d6911ed9c846 7 seconds ago 6.47MB
go/helloworld 2 f7cf3465432c 22 seconds ago 6.47MB
go/helloworld 1 f55d3e16affc 2 minutes ago 295MB
很明显使用多阶段构建的镜像体积小,同时也完美解决了上边提到的问题。 只构建某一阶段的镜像
我们可以使用 as 来为某一阶段命名,例如
FROM golang:1.9-alpine as builder
例如当我们只想构建 builder 阶段的镜像时,我们可以在使用 docker build 命令时加上 --target 参数即可
$ docker build --target builder -t username/imagename:tag . 构建时从其他镜像复制文件
上面例子中我们使用 COPY --from=0 /go/src/github.com/go/helloworld/app . 从上一阶段的镜像中复制文件,我们也可以复制任意镜像中的文件。
$ COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf
Docker学习——多阶段构建(六)的更多相关文章
- docker multi-stage 多阶段构建
多阶段构建 一.需求 二.普通构建 1.编写Dockerfile 2.构建镜像 三.多阶段(multi-stage)构建 1.编写Dockerfile 2.构建镜像 四.比较2个镜像的体积大小 我们在 ...
- Docker学习之4——构建NGINX镜像
Nginx是一个高性能的Web和反向代理服务器,它具有很多非常优越的特性:1.作为Web服务器.2.作为负载均衡服务器.3.作为邮件代理服务器.4.安装及配置简单.接下来我们介绍在docker构建ng ...
- Docker学习(12) Dockerfile构建过程
Dockerfile的构建过程 以上为构建缓存
- Docker学习(六)Dockerfile构建自定义镜像
Docker学习(六)Dockerfile构建自定义镜像 前言 通过前面一篇文章可以知道怎么去使用一个镜像搭建服务,但是,如何构造自己的一个镜像呢,docker提供了dockerfile可以让我们自己 ...
- Docker学习(六): 网络使用与配置
特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! =============系列文章============= 1 ...
- Docker学习(六)——Dockerfile文件详解
Docker学习(六)--Dockerfile文件详解 一.环境介绍 1.Dockerfile中所用的所有文件一定要和Dockerfile文件在同一级父目录下,可以为Dockerfile父目录的子目录 ...
- 多阶段构建Docker镜像
在Docker 17.05及更高的版本中支持支持一种全新的构建镜像模式:多阶段构建: 多阶段构建Docker镜像的最大好处是使构建出来的镜像变得更小: 目前常见的两个构建镜像的方式为: 1.直接使用某 ...
- Docker学习(二): 镜像的使用与构建
特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! =============系列文章============= 1 ...
- Docker多阶段构建实战(multi-stage builds)
在编写Dockerfile构建docker镜像时,常遇到以下问题: RUN命令会让镜像新增layer,导致镜像变大,虽然通过&&连接多个命令能缓解此问题,但如果命令之间用到docker ...
- 多阶段构建Golang程序Docker镜像
Docker简介 Docker是基于Linux容器技术(LXC),使用Go语言实现的开源项目,诞生于2013年,遵循Apache2.0协议.Docker自开源后,受到广泛的关注和讨论. Docker在 ...
随机推荐
- OS复盘
OS复盘 OS课设已经结课一段时间了,我也从其他课程中抽身出来,有了一段能够好好反思的时光. 说实话,完成OS课设的过程是很痛苦的,指导书蜻蜓点水.注释模棱两可.各种函数和文件调用杂乱无章.每次在完成 ...
- ChainofResponsibility Pattern
责任链模式: 参考:https://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html 避免请求发送者与接收者耦合在一 ...
- Win10下如何添加“中文简体(美式键盘)”输入法
参考Win10下如何添加"中文简体(美式键盘)"输入法 设置>>时间和语言>>语言>>添加语言>>选择要安装的语言>>英 ...
- JAVA学习笔记-06
多态:可以理解为事物存在的多种体现形态 1.多态的基本体现 父类的引用指向了自己的子类对象 父类的引用也可以接收自己的子类对象 2.多态的前提 必须是类与类之间有关系,要么继承,要么实现 通常还有一个 ...
- SpringBoot启动流程与自动装配
是什么 Spring Boot基于Spring框架之上的一个微服务架构开发框架大大简化了Spring的开发.因为Spring Boot提供了大量的自动配置.而且它是基于Java配置方式的开发(全注解) ...
- [Oracle19C 数据库管理] 加载和传输数据库
移动数据的通用架构 数据泵data pump(impdp, expdp),借助DBMS_DATAPUMP存储过程,可以进行表的导出导入,行记录的导出导入,表空间的导出导入或者整个schema的导出导入 ...
- excel 巧用功能
1. 分类汇总 数据-->分类汇总--> 解决问题:解决了我按字段分类并分页打印的问题,例如几十个村数据,要按村分页打印相关数据这时不能把村分别复制粘贴到一个一个工作薄,太麻烦了. 处理方 ...
- 面试之AQS
https://blog.csdn.net/wwwzhouzy/article/details/119702170 https://copyfuture.com/blogs-details/20200 ...
- SVD动态图
library(gganimate) library(gifski) # 构造数据 phi<-pi/6 theta<-pi/3 c<-matrix(c(cos(phi),sin(ph ...
- Vulnhub 靶场 DIGITALWORLD.LOCAL: SNAKEOIL
Vulnhub 靶场 DIGITALWORLD.LOCAL: SNAKEOIL 前期准备 靶机地址:https://www.vulnhub.com/entry/digitalworldlocal-sn ...