• Docker 的多阶段构建


    需求

    我们 Build 一个应用的时候,将我们的源代码也构建进去的,这对于类似于 golang 这样的编译型语言肯定是不行的,因为实际运行的时候我只需要把最终构建的二进制包给你就行,把源码也一起打包在镜像中,需要承担很多风险,即使是脚本语言,在构建的时候也可能需要使用到一些上线的工具,这样无疑也增大了我们的镜像体积。所以对于golang语言运行于docker之上的时候,只出现二进制文件即可。

    比如有如下程序需要在docker中运行:

    package main
    import (
        "github.com/gin-gonic/gin"
        "net/http"
    )
    func main() {
        router := gin.Default()
        router.GET("/ping", func(c *gin.Context) {
            c.String(http.StatusOK, "PONG")
        })
        router.Run(":8080")
    }
    

    第一步:原始方式构建镜像

    编写dockerfile文件:

    FROM golang:1.14-alpine
    
    ENV CGO_ENABLED=0
    ENV GOPROXY="http://10.11.100.127/repository/goproxy/"
    
    RUN sed -i "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g" /etc/apk/repositories 
            && apk add --update --no-cache ca-certificates curl make git gcc libtool musl-dev
    
    RUN mkdir /app 
     && mkdir -p /app/static
    COPY . /app
    WORKDIR /app
    RUN go mod vendor && go build -o main
    CMD ["/app/main"]
    

    构建镜像:

    docker build -t demo-test:old .
    

      

    查看镜像:

     

     

     可以看到,镜像文件有570多M。

     

    第二步:取二进制文件构建镜像

    其实我们只需要他的二进制文件,所以需要拿去二进制文件即可:

    docker create --name myapp demo-test:old
    docker cp myapp:/app/app-server ./app-server
    docker rm -f extract
    

    获取二进制文件后,继续编写第二个dockerfile文件: cat Dockerfile.old

    FROM alpine:latest  
    RUN apk add -U tzdata
    RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime
    WORKDIR /root/
    COPY app-server .
    CMD ["./app-server"]
    

      

    查看镜像:

     

     此时可以看到镜像文件只有24.1MB了!

     

    第三步:多阶段构建

    Docker 17.05版本以后,官方就提供了一个新的特性:Multi-stage builds(多阶段构建)。 使用多阶段构建,你可以在一个 Dockerfile 中使用多个 FROM 语句。每个 FROM 指令都可以使用不同的基础镜像,并表示开始一个新的构建阶段。你可以很方便的将一个阶段的文件复制到另外一个阶段,在最终的镜像中保留下你需要的内容即可。

    我们可以调整前面一节的 Dockerfile 来使用多阶段构建:(保存为Dockerfile)

    FROM golang:1.14-alpine as build-env
    
    ENV CGO_ENABLED=0
    ENV GOPROXY="http://10.11.100.127/repository/goproxy/"
    
    RUN sed -i "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g" /etc/apk/repositories 
            && apk add --update --no-cache ca-certificates curl make git gcc libtool musl-dev
    
    RUN mkdir /app 
     && mkdir -p /app/static
    COPY . /app
    WORKDIR /app
    RUN go mod vendor && go build -o /app/main
    
    FROM alpine:latest  
    RUN apk add -U tzdata
    RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime
    COPY --from=build-env /app/main  /usr/local/bin/app-server
    EXPOSE 8080
    CMD ["app-server"]  
    

      注意:COPY中的--from=build-env可以直接使用第一阶段生成的文件,相当于接管了第一阶段的上下文。

     构建镜像:

    docker build -t multi-state-demo:new .
    

      

    查看镜像:

     

     可以看到,多阶段构建和之前分为两步构建,效果一样!

     

     

  • 相关阅读:
    leetcode题目19.删除链表的倒数第N个节点(中等)
    Android学习笔记---使用Service模仿下载效果
    Android学习笔记-简单聊天界面的实现
    Android学习笔记-ContentProvider操作
    Android高级-Android操作SQL数据管理,增删改查
    Android高级-正则表达式
    Android高级-SQL语言
    Android学习之路-录音功能实现
    gitee上传下载代码命令
    opencv进行视频播放每帧处理,读取视频失败
  • 原文地址:https://www.cnblogs.com/skyflask/p/15223414.html
Copyright © 2020-2023  润新知