参考:
版本:
- docker >= 17.05
- ubuntu 18.04 LTS
0.前言
通常在构建docker镜像的时候,我们会用到Dockerfile
,如果对于构建的镜像资源来源有多个的情况下,是不是build
多个Dockerfile
呢?答案是可以不用。
docker在17.05以后的版本中,可以在一个Dockerfile
中使用多个From
,进而构建镜像,这也叫做多阶段构建镜像,multi-stage builds
。每条From
指令对应一个构建阶段,多条From
就是多阶段构建。多阶段构建的意义在于,构建过程中,选择性的将前面阶段中的必要文件复制到后面的阶段中,同时抛弃不需要的文件,最后仅保留需要的文件。
1.示例
以下例子以官方文档做说明。
目录结构:
- Dockerfile
- app.go
app.go code
package main
import "fmt"
func main() {
fmt.Println("Hello, 世界")
}
Dockerfile
FROM golang:1.16 AS builder # 1.以golang:1.16 镜像作为builder镜像
WORKDIR /go/src/github.com/helloworld/ # 2.容器内部的工作目录,下面的go get 命令运行的目录
# RUN go get -d -v golang.org/x/net/html
RUN go get -d -v github.com/go-sql-driver/mysql # 3.go get 包
COPY app.go . # 4.复制文件
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . # 5.运行编译
FROM alpine:latest AS prod # 6.以alpine:latest镜像作为prod镜像
RUN apk --no-cache add ca-certificates # 7.
WORKDIR /root/ # 8.设置/root为工作目录
COPY --from=0 /go/src/github.com/helloworld/app . # 9.整型数字0代表第一个FROM构建的镜像,从该镜像中复制文件
# 上面也可写成如下
# COPY --from=builder /go/src/github.com/helloworld/app .
CMD ["./app"] # 10.运行命令
build阶段
docker build -t sweeneys/helloworld:v1 .
通过以上命令,即可将多个FROM指令实现多阶段构建,结合COPY操作保留前面构建的阶段的文件,进而创建新的镜像。
AS
默认情况,每个构建阶段是没有命名的,通过整型编号进行引用(类似数组下标索引,0-第一个FROM,1-第二个FROM,类推),通过AS <stageName>
在FROM中为每个阶段命名。
如上Dockerfile的AS
的使用。
--target: 构建指定阶段的镜像
在Dockerfile中通过AS指定了阶段名,这时我们可以通过alias别名加--target
参数指定阶段构建镜像。
举个例子:
$ docker build --target builder -t sweeneys/helloworld:targetbuilder .
Sending build context to Docker daemon 3.072kB
Step 1/5 : FROM golang:1.13.5 AS builder
---> ed081345a3da
Step 2/5 : WORKDIR /go/src/github.com/helloworld/
---> Running in 31a2f401fc93
Removing intermediate container 31a2f401fc93
---> 449948e706cf
Step 3/5 : RUN go get -d -v github.com/go-sql-driver/mysql
---> Running in 285dd69a987f
github.com/go-sql-driver/mysql (download)
Removing intermediate container 285dd69a987f
---> 762cee703e08
Step 4/5 : COPY app.go .
---> 64d818cfdb58
Step 5/5 : RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
---> Running in d3a40f14a509
Removing intermediate container d3a40f14a509
---> 7e49d73e0ff2
Successfully built 7e49d73e0ff2
Successfully tagged sweeneys/helloworld:targetbuilder
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
通过docker images
确认下构建成功的镜像。
COPY --from: 构建时从其他镜像复制文件
通过使用COPY --from=0/1/2|images:tag src dst
实现从构建阶段的镜像或者外部镜像,可以是本地也可以是docker hub
的镜像。