对Golang应用程序进行多阶段docker构建的方法

348 阅读1分钟

多阶段构建的目的是使最终的应用程序图像尽可能小,这就是我们在这里要做的。另外,我也会向你展示供应商和非供应商版本的构建。这取决于你的选择,但到目前为止,我从来不需要使用供应商版本,因为Go在依赖性管理方面一直很好。

结构

.
├── cmd
│   └── football
│       └── main.go
├── docker
│   └── dev
│       ├── docker-compose.yaml
│       └── go
│           └── Dockerfile
├── .env.dist
├── go.mod
├── go.sum
└── Makefile

docker-compose.yaml

version: "3.4"

services:

  football-go:
    container_name: "football-go"
    hostname: "football-go"
    build:
      context: "../.."
      dockerfile: "docker/dev/go/Dockerfile"
    restart: "unless-stopped"
    volumes:
      - "../../.env.dist:/.env"

非供应商版本

Docker文件

#
# STAGE 1: prepare
#
FROM golang:1.13.1-alpine3.10 as prepare

WORKDIR /source

COPY go.mod .
COPY go.sum .

RUN go mod download

#
# STAGE 2: build
#
FROM prepare AS build

COPY . .

RUN CGO_ENABLED=0 go build -ldflags "-s -w" -o bin/football cmd/football/main.go

#
# STAGE 3: run
#
FROM scratch as run

COPY --from=build /source/bin/football /football

ENTRYPOINT ["/football"]
较短的版本
#
# STAGE 1: build
#
FROM golang:1.13.1-alpine3.10 as build

WORKDIR /source
COPY . .

RUN CGO_ENABLED=0 go build -ldflags "-s -w" -o bin/football cmd/football/main.go

#
# STAGE 2: run
#
FROM alpine:3.10 as run

COPY --from=build /source/bin/football /football

ENTRYPOINT ["/football"]

构建和运行

假设这些命令是你的Makefile 文件的一部分:

// Prune unused packages and dependencies from go.mod file.
$ go mod tidy -v

// Compile packages and dependencies then run the app.
$ go build -race -ldflags "-s -w" -o bin/football cmd/football/main.go
$ bin/football

供应商版本

Dockerfile

在这种情况下,应用程序根目录下必须有vendor 文件夹。为此,你应该运行底部提到的两个额外的命令,以便准确的依赖关系可以被复制过来:

#
# STAGE 1: prepare
#
FROM golang:1.13.1-alpine3.10 as prepare

WORKDIR /source

COPY vendor .

#
# STAGE 2: build
#
FROM prepare AS build

COPY . .

RUN CGO_ENABLED=0 go build -ldflags "-s -w" -o bin/football cmd/football/main.go

#
# STAGE 3: run
#
FROM scratch as run

COPY --from=build /source/bin/football /football

ENTRYPOINT ["/football"]

构建和运行

假设这些命令是你的Makefile 文件的一部分:

// Prune unused packages and dependencies from go.mod file.
$ go mod tidy -v

// Reset vendor directory to include all dependencies and rebuild.
$ go mod vendor
$ go build -mod vendor ./...

// Compile packages and dependencies then run the app.
$ go build -race -ldflags "-s -w" -o bin/football cmd/football/main.go
$ bin/football