Dockerfile 多阶段构建镜像实践

参考:

版本:

  • 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的镜像。

原文地址:https://www.cnblogs.com/davis12/p/15055145.html