你不觉得它不可怕吗?多阶段构建

将公司的生产环境迁移到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。

广告
将在 10 秒后关闭
bannerAds