Multi-Stage Build を使ってLaravelアプリのイメージを作ってみた。
LaravelとVue.jsの勉強がてらにちまちまとアプリを作っていて、そのLaravelアプリケーションを実行する環境をDocker で構築しているのだけど、以下の2つほど問題があった。
- composer やnpm はアプリを起動させるまでに必要なパッケージのインストールやアセットのコンパイルに必要なのであって、アプリ実行時には必要ない。特に
node_modules
。 - Dockerファイル内でcomposer やnpm のインストールするとなると、その記述やそれぞれのバージョン管理が面倒。
ということで、Docker 17.05以降で使えるようになったマルチステージビルドで解決してみた。 検索してみると、Laravel Newsに丁度いい記事を発見した。
実際に書いてみたのがこちら。
マルチステージビルド
これは、異なるイメージで特定のコマンドを実行し、1つのイメージを作る方法。
例えば、以下のようなDockerfile
があったとする。
FROM composer:1.8.0 as vendor # (1) COPY composer.json composer.json COPY composer.lock composer.lock RUN composer install FROM php-cli:7.2.14 RUN mkdir /app WORKDIR /app COPY . /app COPY --from=vendor /app/vendor/ /app/vendor/ # (2) CMD ["php", "artisan", "server"]
(1) でPHPのパッケージをインストールするために、composer:1.8.0
イメージを使ってインストールしている。
そこでできた成果物、つまりvendor
以下のPHPパッケージをLaravelアプリのイメージを作る際にそのまま利用する(2)。
このように、特定のコマンド(composer)の実行時に必要なイメージ(composer:1.8.0
)を使い、そこでできたものを実際に欲しいイメージ作成時に利用することができる。
ということで、各ステージ毎に何をしているのかがわかりやすくなったし、最終的に作りたいイメージに必要ないものを含めずにコンパクトにできたので、だいぶスッキリした。