Docker 多阶段构建
多阶段构建
多阶段构建是 Docker 17.05 版本引入的新特性,可以让我们在一个 Dockerfile 中定义多个构建阶段,每个阶段可以使用不同的基础镜像,这样可以减少镜像的大小。
dockerfile
FROM golang: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 会按照 FROM
的顺序执行,每个阶段的镜像都可以使用 --from
参数来引用之前的阶段的镜像。
bash
docker build -t imagename:tag .
只构建某一阶段的镜像
我们可以使用 AS
来为某一阶段命名,例如:
dockerfile
FROM golang:alpine AS builder
例如当我们只想构建 builder
阶段的镜像时,增加 --target=builder
参数即可:
bash
docker build --target builder -t imagename:tag .
构建时从其他镜像复制文件
上面例子中我们使用 COPY --from=0
从上一阶段的镜像中复制文件,我们也可以复制任意镜像中的文件。
dockerfile
COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf
环境变量会在多阶段中共享吗
在多阶段构建中,使用 ENV
指令设置的环境变量在多个构建阶段之间是不共享的。每个构建阶段都有自己的环境,并且 ENV
指令在每个阶段都会创建一个新的环境变量。
要在多个构建阶段之间共享环境变量,可以使用 ARG
指令将构建参数传递给多个阶段,然后在每个阶段中使用 ARG
指令设置环境变量。
下面的示例演示了如何在多个构建阶段之间共享环境变量:
dockerfile
ARG VERSION=latest
FROM alpine:${VERSION} AS build
ARG VERSION
RUN echo ${VERSION} > /version
FROM alpine:${VERSION}
ARG VERSION
ENV VERSION=${VERSION}
COPY --from=build /version /version