Dockerコンテナ作成時にcomposer installを効率よくcacheする

2017-02-25
Docker
Composer

方法としてはシンプルで、まずアプリケーションとは別にcomposer.json, composer.lockを適当なディレクトリにコピーする。次にcomposer installを実行して必要なライブラリ群のダウンロードを完了しておく。

1
2
3
4
COPY laravel/composer.json /tmp/composer.json
COPY laravel/composer.lock /tmp/composer.lock
ENV COMPOSER_ALLOW_SUPERUSER 1
RUN composer install --no-scripts --no-autoloader -d /tmp

アプリケーションをコンテナにコピーした後に、先程ダウンロードしておいたvendorディレクトリをアプリ直下に移動する。最後にdump-autoloadコマンドでautoload.phpを生成すればOK。

1
2
RUN mv -n /tmp/vendor ./ \
&& composer dump-autoload

ポイント

普通にアプリケーションのコンテナを作る場合は、アプリケーションのディレクトリ全体をcopyした上でcomposer installを実行する。この場合、composer.jsonに変更が無くても他に変更があればcacheが利用出来なくなってしまうので、殆どの場合はdocker buildする度にcomposer installが実行されてしまう。

アプリケーションよりも先にcomposer installの実行を単独でcacheさせてしまえば、composer.jsonが更新されない限りはcacheが利用されるのでdocker buildで毎回composerが実行されてしまうことを防げる。

手順内でcomposerのオプションとして--no-scritps --no-autoloaderをつけている理由は、アプリケーションによってはpre-install-cmd, post-install-cmdや名前空間の設定処理でコケてしまうためです。アプリケーションのコピー後に、vendorを移動した上でcomposer dump-autoloadを実行するのがコツです。

Node.js界隈で、この知恵が使われていたので真似してみました。

参考

https://github.com/hanhan1978/docker-laravel54-skelton/blob/master/Dockerfile