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

Docker镜像瘦身(slim)是指通过一系列的优化步骤来减少Docker镜像的大小,使其更为轻量。这样不仅可以减少存储空间的需求,还能加速镜像的拉取速度。下面是一些常见的Docker镜像瘦身技巧: 1. 使用基础镜像选择合适的Docker基础镜像(base image)是非常重要的。对于非Windows环境,可以选择`alpine`或`busybox`这类小巧的基础镜像。例如,使用`alpine`作为基础镜像通常能显著减小镜像的大小。 2. 删除不必要的文件在构建镜像的过程中,可以使用`RUN rm -rf`命令删除不再需要的文件或目录,比如编译过程中的临时文件、源代码等。 3. 多阶构建Multi-stage builds)Docker 17.05及以上版本支持多阶构建,可以在最终的镜像中只包含运行时必需的文件。在多阶构建中,可以先在一个阶段构建应用,然后将构建结果复制到最终镜像中。 4. 使用`.dockerignore`文件在构建上下文时,可以使用`.dockerignore`文件排除不需要传递到Docker守护进程的文件和目录,这可以减少构建上下文的大小,从而减少最终镜像的大小。 5. 使用ADD和COPY命令当需要将文件添加到镜像中时,应优先使用`COPY`命令,因为`ADD`命令会进行一些额外的处理,比如自动解压缩等。如果仅需要复制文件而不需要额外功能,`COPY`更为合适。 6. 清理缓存如果在镜像中使用了包管理器(如`apt`或`yum`),确保在安装完需要的包后删除所有缓存文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值