多阶段构建的目的是使最终的应用程序图像尽可能小,这就是我们在这里要做的。另外,我也会向你展示供应商和非供应商版本的构建。这取决于你的选择,但到目前为止,我从来不需要使用供应商版本,因为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