Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
[goose](https://bitbucket.org/liamstask/goose) 専用の Docker イメージを作る

goose のバイナリが入った小さな docker イメージを作る

go getで取得したcliツールのバイナリを持った軽量なDockerイメージをつくる - tehepero note(・ω<) を見てなんとなく挑戦。

ここでやることは static な goose バイナリを用意して scratch イメージに放り込むだけです。

Build

専用の build イメージを作る。キモは build のオプション(-ldflags "-extldflags -static")。go-sqlite3 が cgo なので CGO_ENABLED=0 はできない。正直あまりわかってない。
golangで書いたアプリケーションのstatic link化 - okzkメモ こちらの説明が詳しい。

Build 用イメージの Dockerfile

FROM golang:alpine

RUN set -ex \
        && apk add --no-cache --virtual build-dependencies \
            build-base \
            git \
        && go get -ldflags "-extldflags -static" bitbucket.org/liamstask/goose/cmd/goose \
        && apk del build-dependencies

バイナリの作成と確認

$ docker build -t goose-build .
Sending build context to Docker daemon 12.52 MB
Step 1/2 : FROM golang:alpine
 ---> 00371bbb49d5
Step 2/2 : RUN set -ex && apk add --no-cache --virtual build-dependencies build-base git && go get -ldflags "-extldflags -static" bitbucket.org/liamstask/goose/cmd/goose && apk del build-dependencies
 ---> Running in 53d8cb771563
+ apk add --no-cache --virtual build-dependencies build-base git
fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/community/x86_64/APKINDEX.tar.gz
(1/25) Installing binutils-libs (2.26-r0)
(2/25) Installing binutils (2.26-r0)
(3/25) Installing gmp (6.1.0-r0)
(4/25) Installing isl (0.14.1-r0)
(5/25) Installing libgomp (5.3.0-r0)
(6/25) Installing libatomic (5.3.0-r0)
(7/25) Installing libgcc (5.3.0-r0)
(8/25) Installing pkgconf (0.9.12-r0)
(9/25) Installing pkgconfig (0.25-r1)
(10/25) Installing mpfr3 (3.1.2-r0)
(11/25) Installing mpc1 (1.0.3-r0)
(12/25) Installing libstdc++ (5.3.0-r0)
(13/25) Installing gcc (5.3.0-r0)
(14/25) Installing make (4.1-r1)
(15/25) Installing musl-dev (1.1.14-r14)
(16/25) Installing libc-dev (0.7-r0)
(17/25) Installing fortify-headers (0.8-r0)
(18/25) Installing g++ (5.3.0-r0)
(19/25) Installing build-base (0.4-r1)
(20/25) Installing libssh2 (1.7.0-r0)
(21/25) Installing libcurl (7.52.1-r0)
(22/25) Installing expat (2.1.1-r2)
(23/25) Installing pcre (8.38-r1)
(24/25) Installing git (2.8.3-r0)
(25/25) Installing build-dependencies (0)
Executing busybox-1.24.2-r12.trigger
OK: 174 MiB in 37 packages
+ go get -ldflags -extldflags -static bitbucket.org/liamstask/goose/cmd/goose
+ apk del build-dependencies
WARNING: Ignoring APKINDEX.167438ca.tar.gz: No such file or directory
WARNING: Ignoring APKINDEX.a2e6dac0.tar.gz: No such file or directory
(1/25) Purging build-dependencies (0)
(2/25) Purging build-base (0.4-r1)
(3/25) Purging make (4.1-r1)
(4/25) Purging fortify-headers (0.8-r0)
(5/25) Purging g++ (5.3.0-r0)
(6/25) Purging gcc (5.3.0-r0)
(7/25) Purging binutils (2.26-r0)
(8/25) Purging isl (0.14.1-r0)
(9/25) Purging libatomic (5.3.0-r0)
(10/25) Purging pkgconfig (0.25-r1)
(11/25) Purging pkgconf (0.9.12-r0)
(12/25) Purging libc-dev (0.7-r0)
(13/25) Purging musl-dev (1.1.14-r14)
(14/25) Purging libstdc++ (5.3.0-r0)
(15/25) Purging git (2.8.3-r0)
(16/25) Purging binutils-libs (2.26-r0)
(17/25) Purging mpc1 (1.0.3-r0)
(18/25) Purging mpfr3 (3.1.2-r0)
(19/25) Purging gmp (6.1.0-r0)
(20/25) Purging libgomp (5.3.0-r0)
(21/25) Purging libgcc (5.3.0-r0)
(22/25) Purging libcurl (7.52.1-r0)
(23/25) Purging libssh2 (1.7.0-r0)
(24/25) Purging expat (2.1.1-r2)
(25/25) Purging pcre (8.38-r1)
Executing busybox-1.24.2-r12.trigger
OK: 5 MiB in 12 packages
 ---> 020260dee14f
Removing intermediate container 53d8cb771563
Successfully built 020260dee14f
$ # バイナリを取り出すための仮コンテナの作成
$ docker create --name goose-binary goose-build sh
cc64b47d48ac10353e320a3461ad4959ac975e8eddae257615bda7cb9aa49d7b
$ # バイナリの取り出し
$ docker cp goose-binary:/go/bin/goose .
$ # サイズの確認
$ ls -l goose
-rwxr-xr-x 1 mapk0y mapk0y 12505088  1月 26 23:19 goose*
$ # link の確認
$ ldd goose
        not a dynamic executable
$ docker rm goose-binary
goose-binary

実行環境

実行用イメージの Dockerfile

FROM scratch

COPY goose /usr/local/bin/

ENTRYPOINT ["/usr/local/bin/goose"]
CMD ["--help"]

実行イメージの作成とサイズや動作確認

$ docker build -t goose .
Sending build context to Docker daemon 25.02 MB
Step 1/4 : FROM scratch
 ---> 
Step 2/4 : COPY goose /usr/local/bin/
 ---> Using cache
 ---> b8b25c90e4b8
Step 3/4 : ENTRYPOINT /usr/local/bin/goose
 ---> Using cache
 ---> 21e480db0fdc
Step 4/4 : CMD --help
 ---> Using cache
 ---> a1dd0ae6ad8e
Successfully built a1dd0ae6ad8e

$ # サイズの確認
$ docker images goose
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
goose               latest              a1dd0ae6ad8e        About an hour ago   12.51 MB
$ docker images goose-build
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
goose-build         latest              020260dee14f        10 minutes ago      299.5 MB

$ # 動作確認
$ docker run -t --rm goose 

goose is a database migration management system for Go projects.

Usage:
    goose [options] <subcommand> [subcommand options]

Options:
  -env string
        which DB environment to use (default "development")
  -path string
        folder containing db info (default "db")
  -pgschema string
        which postgres-schema to migrate (default = none)

Commands:
    up         Migrate the DB to the most recent version available
    down       Roll back the version by 1
    redo       Re-run the latest migration
    status     dump the migration status for the current DB
    create     Create the scaffolding for a new migration
    dbversion  Print the current version of the database

まとめ

  • サイズは少し(16.8M -> 12.5M)小さくなった。
  • AlpineLinux 上でなく他のディストリビューションでも動くバイナリができた。
  • ちゃんと動くのか少し不安。
  • 労力に見合ったかは疑問。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.