Dockerfile多阶段构建 go 程序

2023-12-13  本文已影响0人  风亡小窝
# syntax=docker/dockerfile:1

ARG GO_VERSION=1.21
ARG GOLANGCI_LINT_VERSION=v1.52

FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS base

WORKDIR /go/src

COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod \
    go mod download -x

FROM base as build-client
ARG TARGETOS
ARG TARGETARCH
RUN --mount=type=cache,target=/go/pkg/mod \
    --mount=type=bind,target=. \ #挂载代码
    GOOS=$TARGETOS GOARCH=$TARGETARCH go build -v -o /bin/client ./cmd/client

FROM base as build-server
ARG TARGETOS
ARG TARGETARCH
ARG APP_VERSION="v0.0.0+unknown"
RUN --mount=type=cache,target=/go/pkg/mod \
    --mount=type=bind,target=. \ #挂载代码
    GOOS=$TARGETOS GOARCH=$TARGETARCH go build -v -ldflags "-X main.version=$APP_VERSION" -o /bin/server ./cmd/server

FROM scratch AS client
COPY --from=build-client /bin/client /bin/
ENTRYPOINT [ "/bin/client" ]

FROM scratch AS server
COPY --from=build-server /bin/server /bin/
ENTRYPOINT [ "/bin/server" ]

FROM scratch AS binaries
COPY --from=build-client /bin/client /
COPY --from=build-server /bin/server /

FROM golangci/golangci-lint:${GOLANGCI_LINT_VERSION} as lint
WORKDIR /test
RUN --mount=type=bind,target=. \
    golangci-lint run

导出构建后的文件

docker build 
--output=bin  \ #指定导出目录
--target=binaries \ #指定构建阶段
.

多平台构建

docker buildx create --driver=docker-container --name=container

docker buildx build \
--target=binaries \ #指定构建阶段
--output=bin \ #指定导出目录
--builder=container \
--platform=darwin/arm64,windows/amd64,linux/amd64 \
.

Dockerfile中的变量

  1. TARGETOSTARGETARCH

--platform=linux/amd64 会被解析为:TARGETOS=linux TARGETARCH=amd64

  1. BUILDPLATFORM

值为当前构建镜像的平台,例如我当前在mac m1平台上编译镜像,则 BUILDPLATFORM=darwin/arm64

构建过程中挂载的坑

RUN --mount=type=cache,target=/go/pkg/mod \
    --mount=type=bind,target=. \
    GOOS=$TARGETOS GOARCH=$TARGETARCH go build -v -o /bin/client ./cmd/client

当使用 --mount=type=bind,target=.go build -v -o /bin/client /bin/client 必须用绝对路径且可写,不能是 ./bin/client
否则会出现 mkdir ./bin/: read-only file system

推送到dockerhub遇到的坑

  1. 有多个dockerhub账号
  2. 来回切换过
  3. docker buildx build 加上 --push后,会在历史登陆过的所有账号验证token,导致一直出现 insufficient_scope: authorization failed
  4. 解决办法
    我们在使用buildx前新建了一个builder: docker buildx create --driver=docker-container --name=container
    办法就是移除后重建:docker buildx rm container

https://docs.docker.com/build/guide/multi-platform/

上一篇 下一篇

猜你喜欢

热点阅读