你不觉得它不可怕吗?多阶段构建
将公司的生产环境迁移到AWS的EKS上时,我将在文章中记录使用多阶段构建来分发golang应用程序的备忘录。
我先说一下
对不起,Docker对我来说是第一次接触。
我从来没有自己用Docker之类的工具构建过环境,所以这是我第一次创建Docker。
我基本上不太懂,所以请您在看的时候不要抱有太大期望。
关于多阶段构建的问题
https://github.com/moby/moby/pull/31257
简单来说,新的功能使得我们可以通过 COPY –from 来直接引用从某个 FROM 镜像中创建的两个或多个镜像之间的文件,并且可以使用 AS 为中间镜像命名。
只要有一个Go语言的单一可执行文件,就不需要依赖于Go语言环境,例如进行交叉编译之类的。(关于Go语言的其他方面暂且不提)
我们马上开始吗?
基本的文件结构在这里。
├build(ここにbuildの成果物が格納される)
│ └ appname(実行バイナリ)
├cmd(実行ディレクトリ)
│ └ main.go
├configs(設定ファイル関連)
├bitbucket-pipelines.yml
├.env(環境変数設定ファイル)
├docker-compose.yml
├Dockerfile
├go.mod
├go.sum
├Makefile(タスクランナー実行ファイル)
制作文件
基本上,我们将此次操作完全交给Makefile处理,包括go build在内。
关于makefile的配置不在这里写,但是我已经按以下方式配置,确保二进制文件会存放在build目录下。
build:
@go build -ldflags="-w -s" -o build/appname ./cmd/main.go
在终端中执行“make build”命令,将在“build”目录下创建一个名为“appname”的单一可执行文件。
Dockerfile的翻译:
Docker镜像构建文件
FROM golang:1.12.9 as builder
WORKDIR /appname/
ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64
COPY go.mod .
COPY go.sum .
RUN GO111MODULE=on go mod download
COPY . .
RUN make build
FROM alpine
RUN apk update \
&& apk add --no-cache
COPY --from=builder /appname/build /app/build
ENTRYPOINT [ "/app/build/appname" ]
首先,让我解释一下要点。
FROM golang:1.12.9 as builder
使用这个来创建golang的基础镜像,这个称为builder的是为了在之后将这个镜像传递的一个别名。
ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64
COPY go.mod .
COPY go.sum .
RUN GO111MODULE=on go mod download
COPY . .
go.mod是Golang的模块相关配置文件,类似于js的package.json文件。
在当前的go1.13环境中,我认为ENV GO111MODULE=on好像是一个不必要的咒语(如果无法运行,请安装它)。
RUN make build
在这里执行go的构建操作,使用make build命令来触发之前创建的Makefile,因此可以通过这样的命令来执行任务。
请参考以下链接了解有关交叉编译的详细信息:
https://qiita.com/xshirade/items/abeb0d595be27cb6326e
FROM alpine
这是Docker官方提供的一个轻量级Linux镜像。具体链接如下:https://alpinelinux.org/
COPY --from=builder /appname/build /app/build
我把之前在这里构建的可执行二进制文件等复制到这里,这样多阶段构建就完成了。
填补
我认为在进行开发环境等的配置时需要确认是否可以连接到mysql,因此我将通过dokcer-compose.yml进行环境搭建。
version: "3"
services:
mysql:
image: mysql:5.7.26
container_name: db
env_file:
- .env
ports:
- "3306:3306"
volumes:
- db_data:/var/lib/mysql
- ./mysql/scripts/init:/docker-entrypoint-initdb.d
- ./mysql/config:/etc/mysql/conf.d
api:
build: .
depends_on:
- mysql
env_file:
- .env
ports:
- "8080:8080"
volumes:
db_data:
这样就可以了
$ docker-compose up --build -d
请确认在这边是否可以连接(请在go端编写连接MySQL的程序哦)。
最后
如果你有其他更好的建议,我真的希望你能告诉我,因为这是我第一次使用Docker,所以我在试探性地实施。非常感谢您读到最后。
接下来,我想使用bitbucket-pipelines.yml将代码推送到ECR。