LoginSignup
0
1

More than 3 years have passed since last update.

Dockerfile の Multi Stage Build 入門

Last updated at Posted at 2020-02-04

Dockerfile おさらい

FROM nginx:latest
ADD . /usr/share/nginx/html

こういうやつです。

今回のサンプル

この記事で実際に動かすサンプルは Golang で書いた HTTP サーバーです。

main.go
package main

import (
    "encoding/json"
    "net/http"
    "time"
)

func echo(w http.ResponseWriter, r *http.Request) {
    type Response struct {
        Status  int       `json:"status`
        Time    time.Time `json:"time`
        Message string    `json:"message`
    }

    w.Header().Set("Content-Type", "application/json")

    res := &Response{
        Status:  http.StatusOK,
        Time:    time.Now(),
        Message: "Json API Server by Golang on Docker",
    }

    json.NewEncoder(w).Encode(res)
}

func main() {
    http.HandleFunc("/", echo)
    http.ListenAndServe(":8888", nil)
}

今回の作業ディレクトリは ~/docker_msb/ とします。
~/docker_msb/main.go に上記のコードをコピーしてください。

Dockerfile を書く

Dockerfile は ~/docker_msb/dockerfile とします。

MultiStageBuild を使わない場合

# Golang 開発環境のイメージを使用
FROM golang:alpine
# 作業ディレクトリを /sample に指定(存在しない場合は勝手に作成される)
WORKDIR /sample
# main.go を作業ディレクトリにコピー
ADD main.go main.go
# コンテナの8888番ポートを開放
EXPOSE 8888
# コンテナが起動する際に実行されるコマンド # go run main.go 
CMD ["go", "run", "main.go"]

この Dockerfile を作成します。

$ docker build -t docker_s .

このコマンドでイメージを作成します。
今回は比較のためにイメージを作成しておきます。

MultiStageBuild を使う場合

# Golang の開発環境のイメージを build という名前をつけて使用
FROM golang:latest as build
# 作業ディレクトリを /build に指定(存在しない場合は勝手に作成される)
WORKDIR /build
# main.go を作業ディレクトリにコピー
ADD main.go main.go
# Go で main.go をビルド
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o webapp -ldflags "-s -w" main.go

# 空のイメージを使用
FROM scratch as release
# 上の build から /build/webapp を /webapp にコピー
COPY --from=build /build/webapp /webapp
# コンテナの8888番ポートを開放
EXPOSE 8888
# コンテナが起動する際に実行されるコマンド # /webapp
ENTRYPOINT ["/webapp"]

この Dockerfile を作成します。

$ docker build -t docker_m .

このコマンドでイメージを作成します。
今回は比較のためにイメージも作成しておきます。

比較

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker_s            latest              dbfcaa92a174        9 seconds ago       359MB # 使用しない場合
docker_m            latest              d2a160b3620f        49 seconds ago      5.57MB # 使用した場合

size を見ると一目瞭然ですね。
MultiStageBuild を使用しない場合のサンプルでは golang:alpine を使用しているため360MBですが、 golang:latest は800MBもあります。 MultiStageBuild を使用したほうがストレージの容量を圧迫せずに済みます。

まとめ

MultiStageBuild が使えるときは使おう。

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