30
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

Dockerfile Tips

本稿では、Dockerfileを記述する際の「ちょっとしたテクニック」について紹介します。

※ 本稿は元々、取引先向けに記述した文章ですが、取引先から公開について快諾頂いたため、微調整の上ここに公開しています。
2016年8月頃に記述した文章であるため、古い情報を含んでいる可能性もありますのでご注意下さい。もし何かお気づきの点があれば、コメント、編集リクエストを頂ければ幸いです。

1. 本家の「ベストプラクティス」を読む

まずは、本家の公式ドキュメント『Dockerfile のベストプラクティス』(英語版: 『Best practices for writing Dockerfiles』に目を通しましょう。

2. 既存のDockerイメージを検索する

利用したいアプリケーション、ライブラリなどが有名な(利用者の多い)ものである場合、公式のDockerイメージが公開されている場合があります。Docker Hubで検索してみましょう。構築済みのアプリケーション、ライブラリを含むDockerイメージをベースとすることで、より手軽に、より素早く環境を構築できる可能性があります。

ただし、一般ユーザが公開しているDockerイメージは、公式のDockerイメージと比べてセキュリティ上のリスクが高いため、使用する場合は十分に注意しましょう。

3. RUNに与えるコマンド列の&&を行頭に記述する

RUNコマンドで複数のコマンド列を連続して実行する場合、a && baの終了ステータスが0ならbを実行)を
使うことが多いです。その&&を行末ではなく、行頭に書きましょう。

利点

  • コマンドが連続していることが明確になる。
  • (抽象的な表現ですが)「リズム感」が出る。

具体例

protobufをビルドする例:

RUN cd /root \
  && git clone --depth=1 -b release-0_12 --recursive https://github.com/grpc/grpc.git \
  && cd /root/grpc/third_party/protobuf \
  && ./autogen.sh \
  && ./configure --prefix="${INSTDIR_GRPC}" \
  && make -j \
  && make install

4. [Ubuntu/Debian] apt-get installに与えるパッケージリストをソートする

Dockerfile のベストプラクティス』でも紹介されていますが、apt-get installに与えるパッケージのリストをソートしておくと良いです。

利点

  • 誰が書いても同じ順序になる。
  • パッケージ名が重複することを防ぐことができる。

欠点

  • 順序による表現ができなくなる。(例えばパッケージ間の関連など)

具体例

RUN apt-get update \
  && apt-get install --yes --no-install-recommends \
    autoconf \
    build-essential \
    curl \
    git \
    libtool \
    pkg-config \
    unzip \
    zlib1g-dev \
  && rm --recursive --force /var/lib/apt/lists/*

5. [Ubuntu/Debian] apt-get installしたらapt-get cleanする

Dockerfile のベストプラクティス』でも紹介されていますが、apt-get installを実行したらapt-get cleanも実行しましょう。

利点

  • Dockerイメージサイズを小さくできる。

具体例

4. [Ubuntu/Debian] apt-get installに与えるパッケージリストをソートする』を参照のこと。

6. git clone --depth=1を使用する

GitリポジトリのHEAD、または特定のブランチをビルドしたい場合、git cloneコマンドの--depth=1
オプションを使用することで「shallow clone」(浅いクローン)することができます。また、--single-branchオプションを併用することで、より時間を短縮できる可能性があります。

利点

  • git cloneに要する時間が短縮される。
  • Gitリポジトリの取得に必要なストレージサイズが少なく済む。

欠点

  • 指定できるのばブランチ名のみ。タグ名、コミットIDは指定できない。
  • 指定したコミット数分のログしか確認できない。
  • 「shallow clone」したリポジトリに対する操作が限定される。

具体例

3. RUNに与えるコマンド列の&&を行頭に記述する』を参照のこと。

参考: 実験

実際にどの程度の時間差が生じるのかを実験してみました。6倍程度の時間差が生じていること、Counting objectsの数値がかなり小さくなっていることが確認できます。

No パターン 実時間
1 --branchのみ 0m26.482s
2 --branch+--depth=1 0m4.218s
3 --branch+--depth=1+--single-branch 0m4.965s
$ time git clone --branch=release-0_12 https://github.com/grpc/grpc.git
Cloning into 'grpc'...
remote: Counting objects: 188327, done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 188327 (delta 5), reused 3 (delta 3), pack-reused 188310
Receiving objects: 100% (188327/188327), 76.43 MiB | 4.67 MiB/s, done.
Resolving deltas: 100% (141584/141584), done.
Checking connectivity... done.

real    0m26.482s
user    0m13.348s
sys 0m1.696s

$ time git clone --branch=release-0_12 --depth=1 https://github.com/grpc/grpc.git
Cloning into 'grpc'...
remote: Counting objects: 4254, done.
remote: Compressing objects: 100% (2953/2953), done.
remote: Total 4254 (delta 2115), reused 2221 (delta 1216), pack-reused 0
Receiving objects: 100% (4254/4254), 3.70 MiB | 2.61 MiB/s, done.
Resolving deltas: 100% (2115/2115), done.
Checking connectivity... done.

real    0m4.218s
user    0m0.556s
sys 0m0.240s

$ time git clone --branch=release-0_12 --depth=1 --single-branch https://github.com/grpc/grpc.git
Cloning into 'grpc'...
remote: Counting objects: 4254, done.
remote: Compressing objects: 100% (2953/2953), done.
remote: Total 4254 (delta 2115), reused 2221 (delta 1216), pack-reused 0
Receiving objects: 100% (4254/4254), 3.70 MiB | 3.10 MiB/s, done.
Resolving deltas: 100% (2115/2115), done.
Checking connectivity... done.

real    0m4.965s
user    0m0.604s
sys 0m0.220s

参考情報

7. git clone --recursiveを使用する

Gitリポジトリにサブモジュールが含まれている場合、git cloneコマンドの--recursiveオプションを
使用することで、サブモジュールも一括して取得することができます。なお、--recurse-submodulesという別名のオプションも存在します。

利点

  • サブモジュールを取得するコマンド(git submodule update --initなど)を実行する必要がない。

欠点

  • すべてのサブモジュールが必要ではない場合、余分なサブモジュールまで取得してしまう。

具体例

3. RUNに与えるコマンド列の&&を行頭に記述する』を参照のこと。

参考情報

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
30
Help us understand the problem. What are the problem?