Dockerfileベストプラクティス
公式
Dockerfile のベスト・プラクティス
Dockerfile が置いてあるディレクトリにファイルを大量に置かない。
Dockerfile を読み込む時に、一緒に読み込むらしい。(設計ミスでは?)
実行のために本当に必要なリソースのみに絞る。
OSのコマンド群も全部が必要ではないはず。
ビルド
RUN はできる限りまとめる。
コマンド1つごとにレイヤーができてしまう。
不要なファイルは必ず削除する。
不要なファイルが残っているとそれもレイヤーに含まれてしまう。
Debian 系の場合の基本
code:ubuntu.Dockerfile
FROM debian:bullseye
RUN apt-get update -y \
&& DEBIAN_FRONTEND=noninteractive apt-get upgrade -y \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git \
&& apt-get autoremove -y \
&& apt-get clean \
&& rm -rf /var/cache/apt/* /var/lib/apt/lists/
DEBIAN_FRONTEND=noninteractive を付けることで、インタラクティブな処理が入ることを避ける。(コンソールから何かを入力することがないようにする。)
--no-install-recommends を付けることで、おまけで関連パッケージをインストールするのを避ける。
ダウンロードしたファイルなどを削除する。
RHEL 系(CentOS 8 以降)の場合の基本
code:rocky.Dockerfile
FROM rockylinux:8
RUN dnf update -y \
&& dnf upgrade -y --best --allowerasing \
&& dnf install -y --setopt=install_weak_deps=False git \
&& dnf clean all \
&& rm -rf /var/cache/dnf
dnf upgrade -y --best --allowerasing でビルド時の最新のバージョンにアップグレードする(任意)
--setopt=install_weak_deps=False を付けることで、おまけで関連パッケージをインストールするのを避ける。
ダウンロードしたファイルなどを削除する。
ADD と COPY のどちらを使うか?
COPY 時にはワーキングディレクトリを指定する。
code:Dockerfile
WORKDIR /
コンテナ実行時に環境変数を渡すことができるので、それを使えば設定ファイルを持たなくてもよい場合がある。
$ docker run -e KEY=value ...
コピーするかマウントするか? イメージに含むか含まないか?
残さなければならないなら、マウント
残さなくてもよいならば、コピー
リアルタイムで反映させる必要があるなら、マウント
後から変更できるようにするなら、マウント
固定的な内容であればイメージに含める。
変動する内容はイメージに含めない。
ただし、変動する前のデフォルト値はイメージに含めることができる。
実行ユーザーを root 以外にするのが望ましい。(アプリケーションに依る)
コンテナ内の uid, gid はホストの uid, gid と同一になってしまっている。
このため、独立した uid, gid を指定することは不可能になっている。
Docker ファイル内で直接 uid, gid を指定すると、可搬性がなくなる。
/etc/passwd, /etc/group をマウントするのは望ましくない。
環境変数で uid, gid を受け取るようにする。
code:Dockerfile
USER 1000
参考
社内のDockerfileのベストプラクティスを公開します
dockerでvolumeをマウントしたときのファイルのowner問題