zoukankan      html  css  js  c++  java
  • 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 .
    

      

    查看镜像:

     

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

     

     

  • 相关阅读:
    织梦开发——相关阅读likeart应用
    织梦标签教程
    织梦专题调用代码
    HIT 2543 Stone IV
    POJ 3680 Intervals
    HIT 2739 The Chinese Postman Problem
    POJ 1273 Drainage Ditches
    POJ 2455 Secret Milking Machine
    SPOJ 371 Boxes
    HIT 2715 Matrix3
  • 原文地址:https://www.cnblogs.com/skyflask/p/15223414.html
Copyright © 2011-2022 走看看