LoginSignup
1
2

More than 3 years have passed since last update.

怖くないよね?マルチステージビルド

Last updated at Posted at 2019-09-14

会社の本番環境をAWSのEKSに移行することになりその際にgolangのアプリを配布する際に使用したマルチステージビルドについて備忘録を交えながら記事を書いていきます。

先に言うんですけど

すみません僕Docker自体初めてです

今まで特に自分でDockerなどで環境構築をしたことがなかったのでこれが初めてのDocker作成です。
ほとんど分かっていないのでこいつダメやなって思いながら見てください

マルチステージビルドについて
https://github.com/moby/moby/pull/31257

簡単に言うと、fromでから作られた2つの複数のFROMイメージ間のファイルを COPY --from で直接を参照できるようになったのと AS で中間イメージに名前が付けられるようになったと言うものです。

golangってクロスコンパイルなどでシングルバイナリさえあればgolangの実行環境不要ですもんね
(golangにいては割愛します。)

早速やりましょうか

基本的なファイル構成はこちら

├build(ここにbuildの成果物が格納される)
│ └ appname(実行バイナリ)
├cmd(実行ディレクトリ)
│ └ main.go
├configs(設定ファイル関連)
├bitbucket-pipelines.yml
├.env(環境変数設定ファイル)
├docker-compose.yml
├Dockerfile
├go.mod
├go.sum
├Makefile(タスクランナー実行ファイル)

Makefile

基本的には今回は go build なども含めて全てMakefile側に任せています。

makefileに関しての設定はここで書きませんがちゃんとbuild配下にバイナリが入るように以下のように設定しました

build: 

@go build -ldflags="-w -s" -o build/appname ./cmd/main.go

これでmake buildのコマンドをターミナルで実行するとbuild配下にappnameと言うシングルバイナリが作成されます

Dockerfile

Dockerfile
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のbaseimageを作成しますこの as builderと言うのがこの後にこのimageを渡すためのエイリアスになります

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みたいなもの)
https://qiita.com/propella/items/e49bccc88f3cc2407745

ENV GO111MODULE=onはおまじないみたいなもので現行のgo1.13の環境では必要ないと思う(動かなかったらいれてください)

RUN make build 

ここでgoのbuildを行います make buildコマンドは先ほど作成した Makefileのトリガーとして buildを設定していたのでこのようなコマンドでタスクの実行が可能です

クロスコンパイルについてはこちらを参照してください
https://qiita.com/xshirade/items/abeb0d595be27cb6326e

FROM alpine

こちらはDockerの公式が提供している軽量なLinuxのイメージです。
https://alpinelinux.org/

COPY --from=builder /appname/build /app/build

ここで先ほどbuildした実行バイナリの格納ファイル等をこちらにCOPYしています
これでマルチステージビルドの完成です

補足

これでducker build などでもいいのですが開発環境等でmysqlに接続できる等などの確認が必要だと思うのでdokcer-compose.ymlで環境の構築を行います

docker-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へのPUSHをしたいと思います。

1
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2