背景
◯ 経緯
- 開発環境と本番環境で Dockerfile をわけたいと思いました
- 共通部分が多いので条件分岐で対応したいと思いました
- 検索したところ以下の記事がみつかりました
◯ 疑問
- 条件分岐なのに条件分岐していると思しき記述がわからなかった
- 条件分岐をしていると思しき箇所は
FROM ... AS ...
という名前をつけている箇所 - リンク先で掲示されている Dockerfile は以下のようなステップを踏んでいる。これをマルチステージビルドを使って途中で止めることで条件分岐を実現している。
build -> dev -> prod
ビルド -> 開発 -> 本番
マルチステージビルド
本来はステージをわけることで容量を下げることを目的にした機能
イメージ構築にあたり最もチャレンジングなものの1つに、イメージ容量を小さくし続けるというものがあります。
マルチステージ ビルドを使う
1. FROM ... AS ...
でステージに名前をつけることができる
Dockerfile
FROM build as dev # <--- dev という名前のステージ
2. --target
で途中でビルドを止めることができる
# ビルドを dev ステージで止める
docker build . --target dev -t example-dev
3. --from
で指定したステージからファイルを引っ張って来れる
composer:latest
の /usr/bin/composer
から /usr/bin/
にコピーしている。
Dockerfile
# composer本体を持ってくる
COPY --link --from=composer:latest /usr/bin/composer /usr/bin/
4. 各ステージは 0 から作られる
各ステージごとに独立した Dcoker イメージが作成される。各ステージで過去に作った Docker イメージから必要な成果物だけを引っ張ってくる(これは理解が間違っている気がします)。これによってマルチステージビルドを活用することで容量を抑えることができる。
5. CMD コマンドは最後の1つだけ実行される
あれ?開発環境の CMD
と本番環境の CMD
がバッティングしないのかなと思ったのですが、うまい具合にやってくれるそうです。
CMD
はDockerfile
内で一度だけ使用でき、複数のCMD
がある場合は最後のものが使用されます。また、docker run
コマンドで追加の引数を指定すると、それらはCMD
で指定したコマンドに上書きされます。
ChatGPT 先生に聞きました