3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

golangアプリケーションのdockerイメージを小さくしたい

Last updated at Posted at 2018-11-06

なぜやるの?

dockerでアプリを動かすときdocker imageのサイズが大きくなる
このimageサイズをできるだけ小さくしたい

どうやるの?

今回はdocker fileがメインなのgoファイルは共通にしている
使用するプログラムは以下になる
main.go

package main

import (
  "fmt"
  "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
  fmt.Fprintln(w, "Hello, World")
}

func main() {
  http.HandleFunc("/", handler)
  http.ListenAndServe(":8080", nil)
}

簡単なwebサーバでこれを動かしてcurlを叩くとHello, Worldが帰ってくる
ちなみにディレクトリ構成は以下のようになっている

今までのやり方

比較のため今までのdocker fileを紹介する

before/dockerfile

FROM golang:1.10-alpine3.7
ADD ./ ./
RUN go build main.go
CMD [ "/go/main" ]

go build周りのことは簡単にしている
これをdocker buildしてみる

$ docker build -t golang-docker-before before/

Successfully tagged golang-docker-before:latest

これが出てきたらbuildは正常に終わっているだろう
次に`イメージのサイズを見る

REPOSITORY             TAG                 IMAGE ID            CREATED             SIZE
golang-docker-before   latest              b289ef900ec0        3 minutes ago       264MB
golang                 1.10-alpine3.7      7f9031684cc1        3 days ago          257MB

さっき作ったgolagn-docker-beforeのイメージサイズはどうだろうか?
264Mある....でかい
そもそもgolangのイメージが大きい
これを小さくしていく

何が必要か

golangで作成したアプリには何が必要だろうか?
golangでbuildすると一つのファイルが吐き出される
つまりこれだけアレばいいはずである
今回でいうとmain.goでもその他パッケージでもなくmainが必要である

イメージを小さくする

mainのファイルさえあればいいのでmainのファイルをbuild時に取り出す
そこでdockerでマルチステージビルドを使う
マルチステージビルドについてはdocker docsを見るといいだろう
docker fileは以下のようになる

after/dockerfile

FROM golang:1.10-alpine3.7 as build
ADD ./ ./
RUN go build main.go

FROM alpine:latest
COPY --from=build /go/main /app/main
CMD [ "/app/main" ]

docker fileを見てみよう最初のFROMではイメージの横にbuildというのがついている.これは任意の文字をつけることができる
golangのimageを使ってgo buildを行っている
吐き出されたmainはどこにあるかというと/go/mainにあるのでそれだけを取り出す
2つ目にFROMでイメージサイズが小さいalpineを使用する.
COPYで--from=buildでどのimageからCOPYからコピーしてくるbuildは最初のFROMでつけたものを使う
そして/app/mainに持っていく
最後にCMDを指定してあげて終了

修正後のimageサイズは

$ docker build -t golang-docker-after after/
$ docker images

golang-docker-after    latest              c9e1ed0e2383        38 minutes ago      11MB
<none>                 <none>              fece0e20da1f        38 minutes ago      264MB
golang-docker-before   latest              b289ef900ec0        About an hour ago   264MB
golang                 1.10-alpine3.7      7f9031684cc1        3 days ago          257MB
alpine                 latest              196d12cf6ab1        7 weeks ago         4.41MB

golang-docker-afterとgolang-docker-beforeのイメージサイズを比べてみる

結果は以下のようになる
golang-docker-after:11MB
golang-docker-before:264MB

まとめ

そもそもimageサイズを小さくするメリットはdocker pullが速くなることだろう
これはdocker pullを頻繁にやる環境では有効的だと考える.
今回使用したコードはgithubで見ることができる

ありがとうございました

3
1
0

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
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?