之前的做法
在 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学习——多阶段构建(六)的更多相关文章

  1. docker multi-stage 多阶段构建

    多阶段构建 一.需求 二.普通构建 1.编写Dockerfile 2.构建镜像 三.多阶段(multi-stage)构建 1.编写Dockerfile 2.构建镜像 四.比较2个镜像的体积大小 我们在 ...

  2. Docker学习之4——构建NGINX镜像

    Nginx是一个高性能的Web和反向代理服务器,它具有很多非常优越的特性:1.作为Web服务器.2.作为负载均衡服务器.3.作为邮件代理服务器.4.安装及配置简单.接下来我们介绍在docker构建ng ...

  3. Docker学习(12) Dockerfile构建过程

    Dockerfile的构建过程 以上为构建缓存

  4. Docker学习(六)Dockerfile构建自定义镜像

    Docker学习(六)Dockerfile构建自定义镜像 前言 通过前面一篇文章可以知道怎么去使用一个镜像搭建服务,但是,如何构造自己的一个镜像呢,docker提供了dockerfile可以让我们自己 ...

  5. Docker学习(六): 网络使用与配置

    特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! =============系列文章============= 1 ...

  6. Docker学习(六)——Dockerfile文件详解

    Docker学习(六)--Dockerfile文件详解 一.环境介绍 1.Dockerfile中所用的所有文件一定要和Dockerfile文件在同一级父目录下,可以为Dockerfile父目录的子目录 ...

  7. 多阶段构建Docker镜像

    在Docker 17.05及更高的版本中支持支持一种全新的构建镜像模式:多阶段构建: 多阶段构建Docker镜像的最大好处是使构建出来的镜像变得更小: 目前常见的两个构建镜像的方式为: 1.直接使用某 ...

  8. Docker学习(二): 镜像的使用与构建

    特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! =============系列文章============= 1 ...

  9. Docker多阶段构建实战(multi-stage builds)

    在编写Dockerfile构建docker镜像时,常遇到以下问题: RUN命令会让镜像新增layer,导致镜像变大,虽然通过&&连接多个命令能缓解此问题,但如果命令之间用到docker ...

  10. 多阶段构建Golang程序Docker镜像

    Docker简介 Docker是基于Linux容器技术(LXC),使用Go语言实现的开源项目,诞生于2013年,遵循Apache2.0协议.Docker自开源后,受到广泛的关注和讨论. Docker在 ...

随机推荐

  1. 51电子-STC89C51开发板:开发包

    全部内容,请点击: 51电子-STC89C51开发板:<目录> ---------------------------  正文开始  --------------------------- ...

  2. vscore 中 vim 常用快捷键

    谷歌浏览器 ctrl + T 新建一个页面 ctrl + J 查看下载界面 F6 直接搜索 vscore 在 vscore 中使用 vim 建议去掉 ctrl 键的功能捆绑,不然会覆盖掉很多的 vsc ...

  3. python_lib_x_1000_file_csv.py

    #!/usr/bin/python # -*- coding: UTF-8 -*- from lib_config import * from lib.lib_x_0002_decorator_log ...

  4. vue打包后打开index.html文件显示空白页问题

    通过网上的资料发现在vue.config.js中写入再重新打包就可以再index.html中显示. https://blog.csdn.net/m0_51060602/article/details/ ...

  5. matlab读写文件操作

    文件相对路径 在编码中尽可能使用相对路径: 1.当前路径下,直接:' xxx.bin ' 2.在下一级路径下,使用:' .\下一级路径文件名\xxx.bin ' 3.在上一级路径下,使用:' ..\x ...

  6. Spring Boot注册Servlet、Filter、Listener原理

    如何使用 在Spring Boot中注册Servlet.Filter办法主要有3种,下面来看下具体例子,例子都采用Filter,Servlet同理. 第一种,使用FilterRegistrationB ...

  7. 微信小程序-自定义tabbar配置及注意事项

    1.选中要创建tabbar组件的目录,右键选定新建Componen 2.然后编写wxml代码和wxss样式 <cover-view class="tab-bar"> & ...

  8. wpf TreeView右键选中节点弹菜单

    <TreeView x:Name="CustomTreeView" Canvas.Top="1" Canvas.Bottom="1" ...

  9. mysql数据增量及备份操作

    注:当数据库出现异常的时候,我们可以先恢复最近一次的全量备份,接着将增量备份的文件一个一个按顺序恢复即可实现原来数据库的恢复. 还可以使用innobackupex 备份工具. 备份 # 1,开启 bi ...

  10. Drozer实践之sieve

    在模拟器中打开drozer agent 启动连接drozer adb connect 127.0.0.1:xxxxx //adb连接设备,只有模拟器才需要这一步,不同模拟器端口不同 adb forwa ...