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

  • 相关阅读:
    面试90%都会翻车的高并发分布式事务,我劝你好好啃透!
    JVM最多支持多少个线程?你知道吗?
    利用注解 + 反射消除重复代码(Java项目)
    ASP.NET HTTP模拟提交通用类 GET POST
    UPW学习资料整理 .NET C# 转
    前端引擎初步设计稿 -通过配置生成动态页面 ,LandaSugar平台 .NET-C#-MVC
    分享一个ASP.NET 文件压缩解压类 C#
    验证码的种类与实现 C#封装类
    ASP.NET MVC 使用 IOC框架 AutoFac 自动释放数据库资源
    ASP.NET MVC权限验证 封装类
  • 原文地址:https://www.cnblogs.com/davis12/p/15055145.html
Copyright © 2020-2023  润新知