Help us understand the problem. What is going on with this article?

multi stageなDockerfileで中間イメージにタグをつける

More than 1 year has passed since last update.

Google Cloud Container Builder でbuildする時に高速化する為にいろいろ奮闘中
multi stageなDockerfileの中間イメージにタグをつけたい場合があったのでメモ

背景

  • Google Cloud Container Builderでのビルドを高速化する為に、キャッシュに使うイメージを事前にpullしておく必要がある
  • マルチステージなDockerfileのビルド時に最終的なビルド結果のイメージをキャッシュしても、中間イメージのキャッシュが無いので高速化されない
    • 中間イメージのbuildが一番重いので、中間イメージにキャッシュを使って欲しい
    • その為には中間イメージもpushしておく必要がある

multi-stage とは

https://docs.docker.com/develop/develop-images/multistage-build/

簡単に言えば ビルド用のイメージと実行用のイメージを分けたい時に1つのDockerfileで実現する方法 ですかね

  • イメージA でビルド
  • イメージBイメージA でビルドした結果をコピー

ということが出来る為、実行用イメージにはコンパイラ等を入れておく必要が無い分、イメージが軽くなる
→これによってpullが軽くなるので、デプロイも速くなる

multi-stageなDockerfile

https://github.com/yagince/docker-multi-stage-sample

# 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を指定する
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした