概要
Dockerfileの書き方は、人それぞれあると思います。しかし、キャッシュや可読性を考えてDockerfileを記述すると、より効率的に扱うことができます。今回は、どのように書くと、良いのだろうかを自分なりに調べてまとめてみました。始めに、キャッシュについての知識も述べております。ひとまずよく使うコマンドのみ述べております。今後もなにか良い書き方があれば追記予定です。
キャッシュについて
-
COPY
,ADD
コマンドは、ファイルに変更があればキャッシュは使用せず、新規にコピー行う -
RUN apt-get update
などは、コマンドだけを見るため、中身のファイルに変更があったとしても、キャッシュを使用し、以前の状態のままとなる - キャッシュを使用したくない場合は、
--no-cache=true
をつければOK
RUNコマンド
1. インストールコマンドは例に示すようにインストールすること
理由
-
$ apt-get update
を別に分けると、キャッシュを使用するため最新のパッケージがインストールできない可能性がある - レイヤー数は限られているため、なるべく少なくすることが大事
- 最後2行でaptキャッシュをクリーンにし、 /var/lib/apt/lists を削除することでイメージのサイズを減らす
- パッケージはアルファベット順に書く
Dockerfile
RUN apt-get update && apt-get install -y \
aufs-tools \
automake \
build-essential \
curl \
dpkg-sig \
libcap-dev \
libsqlite3-dev \
lxc=1.0* \
mercurial \
reprepro \
ruby1.9.1 \
ruby1.9.1-dev \
s3cmd=1.1.* \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
Dockerfile
# ダメな例
RUN apt-get update # 以前のキャッシュを使用して以後のinstallが古いバージョンとなる可能性あり
RUN apt-get install -y aufs-tools
COPYとADD
1. できるだけCOPYを使うこと
理由
- ADD は複数の機能(ローカル上での tar アーカイブ展開や、リモート URL のサポート)を持ち、一見では処理内容が分からないため
- COPYは、ホスト側のディレクトリをコンテナ側にコピーするだけというシンプルな機能なのでわかりやすい。
2. tarアーカイブを展開したい場合、curl,wgetを使用すること
理由
- ADDで行うと不要なファイルが残るが、curl,wgetだと不要なファイルを削除してくれる
Dockerfile
# ダメな例
ADD http://example.com/big.tar.xz /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
RUN make -C /usr/src/things all
# 良い例
RUN mkdir -p /usr/src/things \
&& curl -SL http://example.com/big.tar.xz \
| tar -xJC /usr/src/things \
&& make -C /usr/src/things all
3. パッケージリストファイルだけを先にコピーしインストールを行い、のちにその他のファイルをコピーする
理由
- あまり変更がないパッケージリストファイルを先にコピーしインストールすることで、キャッシュを使用し早くビルドができる
Dockerfile
COPY requirements.txt /tmp/
RUN pip install /tmp/requirements.txt
COPY . /tmp/
参考