docker多阶镜像(multi-stage)构建

博客作为学习笔记记录,若有理解,表述错误,欢迎指出。

docker 多阶镜像(multi-stage)是为了解决多个容器镜像之间文件拷贝等问题,多阶镜像有几个常用的场景:

1. debug: 用于调试dockerfile的特定阶段

2. 用于测试和debug阶段

Q: 为什么要用多阶镜像

在以前,如果需要从一个容器里把编译好的文件放到另外一个容器执行,需要分开两步操作。

举个栗子:

1、 编译工程的docker,对应dockerfile:

FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
COPY app.go .
RUN go get -d -v golang.org/x/net/html \
  && CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app

2、运行程序的docker

FROM
alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY app .
CMD ["./app"] 

3、 将编译的程序拷到运行的docker里运行

#!/bin/sh

# 构建app可执行文件的docker镜像,运行临时docker容器
# 并把app可执行文件拷贝到host上,
# 删除临时docker容器
echo Building alexellis2/href-counter:build

docker build --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy \  
    -t alexellis2/href-counter:build . -f Dockerfile.build

docker container create --name extract alexellis2/href-counter:build 
docker container cp extract:/go/src/github.com/alexellis/href-counter/app ./app  
docker container rm -f extract

# 构建app执行环境的docker镜像,运行执行环境容器
# 并把app可执行文件拷贝到运行环境docker容器中,
# 删除host上app
echo Building alexellis2/href-counter:latest

docker build --no-cache -t alexellis2/href-counter:latest .
rm ./app

这样做也能实现app到运行环境执行,但会有什么问题呢:

问题1:分开操作,麻烦

问题2:需编多个镜像,然后把app拷出来,占用disk空间

  A:  使用多阶镜像构建方式

     使用多阶镜像后,前面那个操作,可以简化成这样:

FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html 
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest  
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"] 

分析以上dockerfile:

1、 每个阶段stage都可以用不同base image

2、只会保留最后一个stage的镜像,前面的都会摒弃

3、可以在后面的stage使用前面stage的东西,eg:

COPY --from=0 /go/src/github.com/alexellis/href-counter/app .

4、 每个阶段以正数索引,从0开始,也可以通过FROM xxx as <stage-name>方式给每个阶段命名,eg:

FROM golang:1.7.3 as builder
…
COPY --from=builder /go/src/github.com/alexellis/href-counter/app .

5、在多阶中,可以分阶段build,eg:

$ docker build --target builder -t alexellis2/href-counter:latest .

     用途:

     A、 debug

     B、testing

     C、只编某个阶段的镜像

6、 COPY --from=xxx,源image没有限制,eg:

COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf

  from 镜像来源:

    a. 本地image name

    b. 本地image tag

    c. docker registry上的image,tag ID

REF:

https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage

猜你喜欢

转载自blog.csdn.net/ksj367043706/article/details/88776735