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 が使えるときは使おう。