Docker の multi-stage build で golang の 軽量 image を作る
Multi-Stage Build
Docker の 17.05 (ce) から multi-stage build 機能が追加されました。 multi-stage build とは、ベースイメージを複数利用し、多段階で build を行う機能です。
利用シーンはビルド環境とランタイム環境の分離が挙げられます。 ビルド環境とランタイム環境を分けるとランタイムがネイティブである Go のような言語では Docker image を劇的に小さくすることができます。
golang の ベースイメージは 数百 MB ありますが、alpine のような 軽量 Linux イメージ単体では 数 MB のため、効果としては 90 % 以上のダイエットに繋がります。
Docker image サイズを小さくするメリットや、一般的なプラクティスについてはページ下部のリンクが非常に参考になります。
Dockerfile の作成
multi-stage build を使って Go のコンテナアプリケーションを作成するテンプレートです。
Dockerfile の中身はこんな感じになります。
FROM golang:latest as builder ENV CGO_ENABLED=0 ENV GOOS=linux ENV GOARCH=amd64 WORKDIR /go/src/github.com/shotat/light-golang-container-template COPY . . RUN make # runtime image FROM alpine RUN apk add --no-cache ca-certificates COPY --from=builder /go/src/github.com/shotat/light-golang-container-template/app /app EXPOSE 8080 ENTRYPOINT ["/app"]
Multi-stage build なので FROM
が二回登場しています。
一行目の FROM では as xxx
としてビルド環境に名前をつけています。
as で指定した名前は COPY --from=builder /go/src/github.com/shotat/light-golang-container-template/app /app
で参照しています。
builder で GOOS
GOARCH
CGO_ENABLED
の環境変数を指定し、 alpine 用にビルドを行います。
amd64の場合 CGO_ENABLED=0
を指定しないとビルド環境依存が発生してしまうため指定は必須です。
RUN apk add --no-cache ca-certificates
は SSL/TLS 通信を行うために必要で、ほとんどアプリケーションで利用するはずです。
通信の必要がなければ alpine
ではなく busybox
や scratch
を使ってより小さなイメージが作れます。
Build する
ビルド自体は make
だけで簡潔するようにしています。
Makefile
の中身はこんな感じです。パッケージ管理には dep
を使います。
# 適当に設定を書く # NAME := hello # VERSION := v1 # ... all: setup build setup: go get -u github.com/golang/dep/cmd/dep dep ensure build: go build -o app
$ docker build . -t app:dev
アプリケーションの中身です。 適当に外部ライブラリを入れたかったので logger として logrus を使っています。
package main import ( log "github.com/sirupsen/logrus" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { log.Info("Hello") } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) }
実際にビルドしてみます。
$ docker build . -t app:dev
Run !
動かします。
$ docker run --rm -p 8080:8080 app:dev $ curl localhost:8080 # container output time="2017-08-05T12:43:25Z" level=info msg=Hello
無事いい感じに動作しています。 デプロイサイクル短縮の鼓動を感じました。
参考書籍
プログラマのためのDocker教科書 インフラの基礎知識&コードによる環境構築の自動化
- 作者: WINGSプロジェクト阿佐志保
- 出版社/メーカー: 翔泳社
- 発売日: 2015/11/19
- メディア: Kindle版
- この商品を含むブログ (3件) を見る
Docker 実践ガイド (impress top gear)
- 作者: 古賀政純
- 出版社/メーカー: インプレス
- 発売日: 2015/12/17
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る
- 作者: ?橋健一,谷口禎英,井本大登,山崎勝平,大和田純,内村元樹,坂東昌哉,平田敏之,牧大輔,板敷康洋,大?浩崇,穴井宏幸,原口宗悟,久田真寛,ふしはらかん,のざきひろふみ,うらがみ,ひげぽん,池田拓司,はまちや2,竹原,片田雄樹,渋江一晃,WEB+DB PRESS編集部編
- 出版社/メーカー: 技術評論社
- 発売日: 2017/06/24
- メディア: 大型本
- この商品を含むブログを見る
- 作者: 松木雅幸,mattn,藤原俊一郎,中島大一,牧大輔,鈴木健太,稲葉貴洋
- 出版社/メーカー: 技術評論社
- 発売日: 2016/09/09
- メディア: 大型本
- この商品を含むブログ (4件) を見る