zoukankan      html  css  js  c++  java
  • 如何使用一个 Dockerfile 文件描述多个镜像

    我们知道在 Docker v17.05 版本后就开始支持多阶段构建 (multistage builds)了,使用多阶段构建我们可以加速我们的镜像构建,在一个 Dockerfile 文件中分不同的阶段来处理镜像。

    例如,如下所示的多阶段构建的 Dockerfile 文件:

    FROM golang:1.9-alpine as builder
    
    RUN apk --no-cache add git
    
    WORKDIR /go/src/github.com/go/helloworld/
    
    RUN go get -d -v github.com/go-sql-driver/mysql
    
    COPY app.go .
    
    RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
    
    FROM alpine:latest as prod
    
    RUN apk --no-cache add ca-certificates
    
    WORKDIR /root/
    
    COPY --from=0 /go/src/github.com/go/helloworld/app .
    
    CMD ["./app"]
    

    构建镜像

    $ docker build -t go/helloworld:3 .
    

    这样构建出来的镜像容量也非常小。

    除此之外,Docker 多阶段构建还可以只构建某一阶段的镜像,比如我们一个项目中由于需求可能会最终打包成多个 Docker 镜像,我们当然可以为每一个镜像单独编写一个 Dockerfile,但是这样还是比较麻烦。遇到这种需求我们就可以直接使用多阶段构建来解决。如下所示的 Dockerfile:

    #
    # BUILD ENVIRONMENT
    # -----------------
    ARG GO_VERSION
    FROM golang:${GO_VERSION} as builder
    
    RUN apt-get -y update && apt-get -y install upx
    
    WORKDIR /workspace
    COPY go.mod go.mod
    COPY go.sum go.sum
    RUN go mod download
    
    # Copy the go source
    COPY main.go main.go
    COPY api/ api/
    COPY controllers/ controllers/
    COPY internal/ internal/
    COPY webhooks/ webhooks/
    COPY version/ version/
    COPY cmd/ cmd/
    
    ENV CGO_ENABLED=0
    ENV GOOS=linux
    ENV GOARCH=amd64
    ENV GO111MODULE=on
    
    # Do an initial compilation before setting the version so that there is less to
    # re-compile when the version changes
    RUN go build -mod=readonly "-ldflags=-s -w" ./...
    
    ARG VERSION
    
    # Compile all the binaries
    RUN go build -mod=readonly -o manager main.go
    RUN go build -mod=readonly -o proxy cmd/proxy/main.go
    RUN go build -mod=readonly -o backup-agent cmd/backup-agent/main.go
    RUN go build -mod=readonly -o restore-agent cmd/restore-agent/main.go
    
    RUN upx manager proxy backup-agent restore-agent
    
    #
    # IMAGE TARGETS
    # -------------
    FROM gcr.io/distroless/static:nonroot as controller
    WORKDIR /
    COPY --from=builder /workspace/manager .
    USER nonroot:nonroot
    ENTRYPOINT ["/manager"]
    
    FROM gcr.io/distroless/static:nonroot as proxy
    WORKDIR /
    COPY --from=builder /workspace/proxy .
    USER nonroot:nonroot
    ENTRYPOINT ["/proxy"]
    
    FROM gcr.io/distroless/static:nonroot as backup-agent
    WORKDIR /
    COPY --from=builder /workspace/backup-agent .
    USER nonroot:nonroot
    ENTRYPOINT ["/backup-agent"]
    
    FROM gcr.io/distroless/static as restore-agent
    WORKDIR /
    COPY --from=builder /workspace/restore-agent .
    USER root:root
    ENTRYPOINT ["/restore-agent"]
    

    我们可以看到在这一个 Dockerfile 中我们使用多阶段构建定义了很多个 Targets,当我们在构建镜像的时候就可以通过 --target 参数来明确指定要构建的 Targets 即可,比如我们要构建 controller 这个目标镜像,则直接使用下面的命令构建即可:

    $ docker build --target controller 
      --build-arg GO_VERSION=${GO_VERSION} 
      --build-arg VERSION=$(VERSION) 
      --tag ${DOCKER_REPO}/${DOCKER_IMAGE_NAME_PREFIX}controller:${DOCKER_TAG} 
      --file Dockerfile .
    

    同样要构建其他的目标镜像则将 target 的参数值替换成阶段定义的值即可。这样我们就用一个 Dockerfile 文件定义了多个镜像。

    参考链接

    现在学习还不晚;
  • 相关阅读:
    Flink sql 写 Hbase 忽略空列
    python协程系列(一)——生成器generator以及yield表达式详解
    Python中可迭代对象,迭代器和生成器的异同点
    Python生成器: send函数、close函数与yield关键字协作
    sqlalchemy的基本用法
    Windows10激活后又提示未激活解决办法
    parseaddr函数和formataddr函数的用法
    VisualStudio Code Remote 调试方法(错误Containers Docker version 17.12.0 or later required.)
    SpringBoot Jar Windows CMD 运行卡顿
    使用Aspose.cells(java)将excel转为图片等
  • 原文地址:https://www.cnblogs.com/ainimore/p/14077796.html
Copyright © 2011-2022 走看看