Google Cloud Container Builder でbuildする時に高速化する為にいろいろ奮闘中
multi stageなDockerfileの中間イメージにタグをつけたい場合があったのでメモ
背景
- Google Cloud Container Builderでのビルドを高速化する為に、キャッシュに使うイメージを事前にpullしておく必要がある
- マルチステージなDockerfileのビルド時に最終的なビルド結果のイメージをキャッシュしても、中間イメージのキャッシュが無いので高速化されない
- 中間イメージのbuildが一番重いので、中間イメージにキャッシュを使って欲しい
- その為には中間イメージもpushしておく必要がある
multi-stage とは
簡単に言えば ビルド用のイメージと実行用のイメージを分けたい時に1つのDockerfileで実現する方法
ですかね
-
イメージA
でビルド -
イメージB
にイメージA
でビルドした結果をコピー
ということが出来る為、実行用イメージにはコンパイラ等を入れておく必要が無い分、イメージが軽くなる
→これによってpullが軽くなるので、デプロイも速くなる
multi-stageなDockerfile
# build stage
FROM rust:1.26.1-slim-stretch AS build-stage
RUN mkdir -p /app
WORKDIR /app
COPY . /app
RUN cargo build --release
# runtime stage
FROM debian:stretch-slim
COPY --from=build-stage /app/target/release/multi-stage /usr/bin/multi-stage
ENTRYPOINT ["/usr/bin/multi-stage"]
やってることは↓こんな感じ
- 前半
- Rustのコンパイラ入りイメージをベースイメージにする
- Rustのアプリケーションをコンパイル
- 後半
- 前半のイメージでビルドした結果を
COPY --from
で新しいイメージにコピーする
- 前半のイメージでビルドした結果を
こんな感じのDockerfileをビルドしてみます
> docker build -t multi-stage .
Sending build context to Docker daemon 10.75kB
Step 1/8 : FROM rust:1.26.1-slim-stretch AS build-stage
1.26.1-slim-stretch: Pulling from library/rust
f2aa67a397c4: Pull complete
fe1b9f79bfd7: Pull complete
Digest: sha256:b0f6f5d661a8d23f0e7c7cb074bde9d278ca0f83d317f7ac2788720943c463f3
Status: Downloaded newer image for rust:1.26.1-slim-stretch
---> b918abbd27e1
Step 2/8 : RUN mkdir -p /app
---> Running in 4bc7eeb1dcd6
Removing intermediate container 4bc7eeb1dcd6
---> 57ebb94df725
Step 3/8 : WORKDIR /app
Removing intermediate container e9026893de00
---> 676390dab381
Step 4/8 : COPY . /app
---> b7dd4f593319
Step 5/8 : RUN cargo build --release
---> Running in b2cea00fa646
Updating registry `https://github.com/rust-lang/crates.io-index`
Downloading regex v1.0.0
Downloading regex-syntax v0.6.0
Downloading utf8-ranges v1.0.0
Downloading thread_local v0.3.5
Downloading aho-corasick v0.6.4
Downloading memchr v2.0.1
Downloading ucd-util v0.1.1
Downloading lazy_static v1.0.1
Downloading unreachable v1.0.0
Downloading void v1.0.2
Downloading libc v0.2.42
Compiling void v1.0.2
Compiling libc v0.2.42
Compiling ucd-util v0.1.1
Compiling lazy_static v1.0.1
Compiling regex v1.0.0
Compiling utf8-ranges v1.0.0
Compiling unreachable v1.0.0
Compiling thread_local v0.3.5
Compiling regex-syntax v0.6.0
Compiling memchr v2.0.1
Compiling aho-corasick v0.6.4
Compiling multi-stage v0.1.0 (file:///app)
Finished release [optimized] target(s) in 22.23 secs
Removing intermediate container b2cea00fa646
---> 792416763821
Step 6/8 : FROM debian:stretch-slim
stretch-slim: Pulling from library/debian
f2aa67a397c4: Already exists
Digest: sha256:aa33563fd6dc2b14e8cae20cc74f4581d4cb89a3952d87b4cab323707040f035
Status: Downloaded newer image for debian:stretch-slim
---> 26f0bb790e25
Step 7/8 : COPY --from=build-stage /app/target/release/multi-stage /usr/bin/multi-stage
---> 0d1cfeee975b
Step 8/8 : ENTRYPOINT ["/usr/bin/multi-stage"]
---> Running in b4cbffcbfda3
Removing intermediate container b4cbffcbfda3
---> 9ea83a0f3562
Successfully built 9ea83a0f3562
Successfully tagged multi-stage:latest
❯ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
multi-stage latest 9ea83a0f3562 2 minutes ago 61.8MB
<none> <none> 792416763821 2 minutes ago 1.08GB
こんな感じでイメージは2つできている。
<none>
の方が前半のイメージですね。
一応、ビルドしたイメージをrunしてみます
❯ docker run --rm multi-stage
Captures({0: Some("2010-03-14"), "year": Some("2010"), "month": Some("03"), "day": Some("14")})
中身はregexのサンプルコードなので、適当に正規表現でキャプチャした結果が出力されます。
無事実行できてますね。
本題: 中間イメージにタグをつける
やっと本題です。
今、 <none>
になっているビルド用の中間イメージにtagをつけたいです。
答えは簡単で
https://docs.docker.com/engine/reference/commandline/build/
docker build
の --target
オプションを使います
> docker build --target build-stage -t multi-stage:build-stage .
Sending build context to Docker daemon 10.75kB
Step 1/5 : FROM rust:1.26.1-slim-stretch AS build-stage
---> b918abbd27e1
Step 2/5 : RUN mkdir -p /app
---> Using cache
---> 57ebb94df725
Step 3/5 : WORKDIR /app
---> Using cache
---> 676390dab381
Step 4/5 : COPY . /app
---> Using cache
---> b7dd4f593319
Step 5/5 : RUN cargo build --release
---> Using cache
---> 792416763821
Successfully built 792416763821
Successfully tagged multi-stage:build-stage
(cacheが効いてれば速攻終わる)
❯ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
multi-stage latest 9ea83a0f3562 14 minutes ago 61.8MB
multi-stage build-stage 792416763821 14 minutes ago 1.08GB
先程 <none>
だった IMAGE ID と 同じimageにtagがついてますね。
あとは、これをpushしておいて、
使う時にはpull
して--cache-from
に指定すればcacheとして使うことが出来ます。
まとめ
- 中間イメージにtagをつけたい時は、
docker build --target
オプションでstageを指定する