多阶段构建
之前的做法:
在Docker17.05版本之前,构建Docker镜像,通常采用两种方式:
1.全部放入一个Dockerfile
一种方式是将所有的构建过程全都包含在一个Dockerfile中,包括项目及其依赖库的编译、测试、打包流程,这里会带来的一些问题:
镜像层次多,镜像体积较大,部署时间变长
源代码存在泄漏的风险
例如,编写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 . 构建完之后查下 docker image ls
输出:
REPOSITORY TAG IMAGE ID CREATED SIZE
go/helloworld 1 abdac4fc2d71 18 seconds ago 260MB 启动 docker run abdac4fc2d71 ,输出 Hello World! ,说明没问题。 2.第二种方式就是分散到多个Dockerfile
事先在一个Dockerfile将项目及其依赖库编译测试打包好后,再将其拷贝到运行环境中,这种方式需要编写两个Dockerfile和一些编译脚本才能将其两个阶段自动整合起来,这种方式虽然可以很好的规避第一种方式存在的风险,但明显部署过程复杂。
例子: app.go文件
--------------------------
package main
import "fmt"
func main(){
fmt.Printf("Hello World!");
} 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 文件
--------------------------
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
54
/ 然后执行build.sh 这个脚本
加个执行权限 chmod +x build.sh
./build.sh PS:如果是windows环境下创建的build.sh这个文件的话,直接放到linux上会有问题,报错会是说XXX文件路径不存在,我的这个就是,最简答的处理方法就是 用vim打开build.sh这个文件,然后执行:set fileformat=unix 然后再 wq 保存退出就行了。 看下镜像 docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
go/helloworld 2 411821efb026 4 minutes ago 7.97MB
go/helloworld build e43c3b88e2c2 4 minutes ago 258MB
go/helloworld 1 abdac4fc2d71 2 hours ago 260MB
ubuntu 18.04 775349758637 4 weeks ago 64.2MB
alpine latest 965ea09ff2eb 5 weeks ago 5.55MB
hello-world latest fce289e99eb9 11 months ago 1.84kB
golang 1.9-alpine b0260be938c6 15 months ago 240MB 最上面的那个就是了,可以跑下试试:docker run 411821efb026 可以输出Hello World! 上面就是两种之前的创建镜像的方式,接下来的笔记是关于 多阶段构建的 Docker v17.05之后开始支持多阶段构建(multistage builds) 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 a
pp .
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 run 0186e09ebd69 可以跑出来Hello World! 对比下体积看看 docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
go/helloworld 3 0186e09ebd69 36 seconds ago 7.97MB
go/helloworld 2 411821efb026 55 minutes ago 7.97MB
go/helloworld build e43c3b88e2c2 55 minutes ago 258MB
go/helloworld 1 abdac4fc2d71 3 hours ago 260MB TAG为3的这个镜像非常小。 只构建某一阶段的镜像
使用 as 来为某一阶段命名,例如 FROM golang:1.9-alpine as builder
如当只想构建 builder 阶段的镜像时,增加 --target=builder 参数即可
docker build --target builder -t username/imagename:tag . 构建时从其他镜像复制文件 使用 COPY --from=0
例子:
COPY --from=0 /go/src/github.com/go/helloworld/app .
COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf

Dockerfile多阶段构建的更多相关文章

  1. Dockerfile多阶段构建原理和使用场景

    本文转载自Dockerfile多阶段构建原理和使用场景 导语 Docker 17.05版本以后,新增了Dockerfile多阶段构建.所谓多阶段构建,实际上是允许一个Dockerfile 中出现多个 ...

  2. Dockerfile 多阶段构建实践

    写在前面 在Docker Engine 17.05 中引入了多阶段构建,以此降低构建复杂度,同时使缩小镜像尺寸更为简单.这篇小作文我们来学习一下如何编写实现多阶段构建的Dockerfile 关于doc ...

  3. 多阶段构建Docker镜像

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

  4. [Docker] 使用 Dockerfile 的多级构建 (multi-stage builds)

      Multi-stage build 即在一个 Dockerfile 中使用多个 FROM 指令.   每个 FROM 指令可以使用不同的基础镜像,并且每一个都开启新的构建阶段.   你可以有选择地 ...

  5. docker 多阶段构建

    构建镜像最具挑战性的一点是使镜像大小尽可能的小.Dockerfile中的每条指令都为图像添加了一个图层,您需要记住在移动到下一层之前清理任何不需要的工件.对于多阶段构建,您可以在Dockerfile中 ...

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

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

  7. 《Docker从入门到跑路》之多阶段构建

    多阶段构建就是在一个Dokcerfile中定义多个FROM,每个FROM都可以使用不同的基础镜像,并表示开始一个新的构建阶段,我们可以很方便的将一个阶段的文件复制到另外一个阶段中,在最终的阶段保存你需 ...

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

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

  9. 使用 Docker 开发 - 使用多阶段构建镜像

    多阶段构建是一个新特性,需要 Docker 17.05 或更高版本的守护进程和客户端.对于那些努力优化 Dockerfiles 并使其易于阅读和维护的人来说,多阶段构建非常有用. 在多阶段构建之前 构 ...

随机推荐

  1. Magicodes.IE Excel合并行数据导入教程

    说明 Magicodes.IE.Excel目前已支持合并行单元格导入,如本篇教程所示. 安装包Magicodes.IE.Excel Install-Package Magicodes.IE.Excel ...

  2. Java基础:特性write once;run anywhere!

    三高:高可用 高性能 高并发 特性: 简单性 面向对象:万物皆为对象 可移植性 高性能 分布式 动态性 多线程 安全性 健壮性 Java三大版本 javaSE:标准版(桌面程序,控制台) javaME ...

  3. 【java框架】MyBatis-Plus(1)--MyBatis-Plus快速上手开发及核心功能体验

    1.MyBatis-Plus入门开发及配置 1.1.MyBatis-Plus简介 MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变, ...

  4. python创建一个二维列表

    方法一:利用for-in语句来生成一个二维列表 a = [] 2 for i in range(10): 3 a.append([]) 4 for j in range(10): 5 a[i].app ...

  5. winnt.h

    winnt.h https://docs.microsoft.com/en-us/windows/win32/api/winnt/ /*++ BUILD Version: 0091 Increment ...

  6. 都在讲Redis主从复制原理,我来讲实践总结

    摘要:本文将演示主从复制如何配置.实现以及实现原理,Redis主从复制三大策略,全量复制.部分复制和立即复制. 本文分享自华为云社区<Redis主从复制实践总结>,原文作者:A梦多啦A . ...

  7. 【pytorch学习笔记0】-CNN与LSTM输入输出维度含义

    卷积data的四个维度: batch, input channel, height, width Conv2d的四个维度: input channel, output channel, kernel, ...

  8. PAT (Advanced Level) Practice 1027 Colors in Mars (20 分) 凌宸1642

    PAT (Advanced Level) Practice 1027 Colors in Mars (20 分) 凌宸1642 题目描述: People in Mars represent the c ...

  9. Java中对象的生与灭- 核心篇

    前言 大家好啊,我是汤圆,今天给大家带来的是<Java中对象的生与灭- 核心篇>,希望对大家有帮助,谢谢 文章纯属原创,个人总结难免有差错,如果有,麻烦在评论区回复或后台私信,谢啦 简介 ...

  10. Vue.js 带下拉选项的输入框(Textbox with Dropdown)组件

    带下拉选项的输入框 (Textbox with Dropdown) 是既允许用户从下拉列表中选择输入又允许用户自由键入输入值.这算是比较常见的一种 UI 元素,可以为用户提供候选项节省操作时间,也可以 ...