warning
この記事は2年以上前に更新されたものです。情報が古くなっている可能性があります。

gcr.io/paketo-buildpacks/builder:tinyでGolangのアプリケーションのOCIイメージを作成します。

BuilderとStackを予めpullしておいてください。

docker pull gcr.io/paketo-buildpacks/builder:tiny
docker pull gcr.io/paketo-buildpacks/run:tiny-cnb

次のコマンドで"Hello World"アプリケーションを作成します。

cd ${GOPATH}/src
mkdir -p github.com/making/hello-golang
cd github.com/making/hello-golang
go mod init

cat <<'EOF' > main.go
package main

import (
  "fmt"
  "net/http"
)

func main() {
  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello World!")
  })
  http.ListenAndServe(":8080", nil)
}
EOF

pack buildコマンドでイメージを作成します。

pack build making/pack-golang --no-pull --builder gcr.io/paketo-buildpacks/builder:tiny

BuilderとStackを事前にpullしていない場合は--no-pullを外せば、ビルド時にBuilderとStackもpullしますが、ビルドが遅くなります。

次のようなログが出力されます。

===> DETECTING
[detector] paketo-buildpacks/go-compiler 0.0.112
[detector] paketo-buildpacks/go-mod      0.0.96
===> ANALYZING
[analyzer] Previous image with name "index.docker.io/making/pack-golang:latest" not found
===> RESTORING
===> BUILDING
[builder] 
[builder] Go Compiler Buildpack 0.0.112
[builder]   Go 1.13.9: Contributing to layer
[builder]     Downloading from https://buildpacks.cloudfoundry.org/dependencies/go/go-1.13.9-tiny-aa89f235.tgz
[builder]     Verifying checksum
[builder]     Expanding to /layers/paketo-buildpacks_go-compiler/go
[builder] 
[builder] Go Mod Buildpack 0.0.96
[builder] Setting environment variables
[builder]   : Contributing to layer
[builder] github.com/making/hello-golang
[builder]   : Contributing to layer
[builder] Running `go install`
[builder]   : Contributing to layer
[builder] Contributing start command
[builder]   Process types:
[builder]     web: /layers/paketo-buildpacks_go-mod/app-binary/bin/hello-golang
===> EXPORTING
[exporter] Adding layer 'launcher'
[exporter] Adding layer 'paketo-buildpacks/go-mod:app-binary'
[exporter] Adding 1/1 app layer(s)
[exporter] Adding layer 'config'
[exporter] *** Images (6e4955319bbd):
[exporter]       index.docker.io/making/pack-golang:latest
[exporter] Adding cache layer 'paketo-buildpacks/go-compiler:aa89f23581019633b2076cc4bd27c441010e03a7dceae992724a9ecadb6cd983'
[exporter] Adding cache layer 'paketo-buildpacks/go-compiler:go'
[exporter] Adding cache layer 'paketo-buildpacks/go-mod:go-cache'
[exporter] Adding cache layer 'paketo-buildpacks/go-mod:go-mod'
Successfully built image making/pack-golang

pack build時に--publishオプションをつけると、Docker Registryでのpushを行います。事前にdocker loginが必要です。

作成したイメージをdocker runで起動します。

docker run --rm -p 8080:8080 making/pack-golang

アプリケーションにアクセスします。

$ curl localhost:8080 -w '\n'
Hello World!

Docker Imageのサイズを確認します。

$ docker images | grep making/pack-golang
making/pack-golang                   latest              6e4955319bbd        40 years ago        29.3MB

使用されるBuildpackは同じですが、ベースイメージのサイズが小さい(Distroless相当)ため、gcr.io/paketo-buildpacks/builder:baseでビルドした場合に比べてイメージサイズが大きいです。

ちなみに、次のDockerfileで作成したDistrolessベースのDocker Imageとサイズを比較してみます。

cat <<'EOF' > Dockerfile
# Start by building the application.
FROM golang:1.13-buster as build

WORKDIR /go/src/app
ADD . /go/src/app

RUN go get -d -v ./...

RUN go build -o /go/bin/app

# Now copy it into our base image.
FROM gcr.io/distroless/base-debian10
COPY --from=build /go/bin/app /
CMD ["/app"]
EOF
docker build -t making/distroless-golang .

サイズは

$ docker images | grep making/distroless-golang
making/distroless-golang             latest              a169522d9c1e        9 seconds ago       26.6MB

です。

gcr.io/paketo-buildpacks/builder:tinyで作成した場合はDistrolessにサイズに引けを取らない一方、
Dockerfileのメンテナンスやベースイメージの更新をpackに任せられる点がメリットです。

pack inspect-imageでイメージを解析します。

$ pack inspect-image making/pack-golang
Inspecting image: making/pack-golang

REMOTE:
(not present)

LOCAL:

Stack: org.cloudfoundry.stacks.tiny

Base Image:
  Reference: 99c5d2da8ae1f1f0e1faa23250b4d0832271a373c494cdee372576314d055ac6
  Top Layer: sha256:3484c5179d3117e509d66b0cde5e8aee264162e05b3dc2ce7b337c74b9767ed0

Run Images:
  gcr.io/paketo-buildpacks/run:tiny-cnb

Buildpacks:
  ID                                   VERSION
  paketo-buildpacks/go-compiler        0.0.112
  paketo-buildpacks/go-mod             0.0.96

Processes:
  TYPE                 SHELL        COMMAND                                                             ARGS
  web (default)                     /layers/paketo-buildpacks_go-mod/app-binary/bin/hello-golang   

Golang Buildpackの細かい設定は
https://github.com/paketo-buildpacks/go
を確認してください。

おわったらDocker Imageを削除します。

docker rmi making/pack-golang
Found a mistake? Update the entry.
Share this article: