Composer のアップグレードに学ぶ Dockerfile FROM 命令のタグ指定
はじめに
あるプロジェクトで Laravel 環境を Docker で構築して開発しています。その中で、個人的にちょっとした学びがあったのでまとめてみました。
➜ docker -v
Docker version 20.10.5, build 55c4c88
開発環境のコンテナ
下記がローカルで動かしているコンテナの Dockerfile です。
FROM php:7.4-fpm-alpine
COPY php.ini /usr/local/etc/php/
ARG TZ
COPY /usr/bin/composer /usr/bin/composer
ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME /composer
RUN composer config -g repos.packagist composer https://packagist.jp
RUN composer global require hirak/prestissimo
RUN docker-php-ext-install pdo_mysql opcache
Dockerfile の詳細
マルチステージビルド
名前の通り、複数のビルドステージに分割してイメージのビルドを行います。この手法を用いることのメリットとしては、ビルド用のイメージとランタイムとして動くアプリケーションのイメージを分離できること、イメージサイズの軽量化などが挙げられます。
こちらの Dockerfile では、公式の Composer イメージを利用しています。
COPY /usr/bin/composer /usr/bin/composer
マルチステージビルドについて詳しく言及しないので、知らなかったという方は是非下記の記事をご一読ください。
hirak/prestissimo
続いて導入しているライブラリについてです。
このライブラリは、composer でのパッケージインストールを並列で行ってくれるものです。それによりパッケージインストールの高速化が狙えるので、毎回入れるようにしています。
今回の問題
上記の Dockerfile をビルドすると下記のようなエラーが出ます。
➜ docker build --no-cache .
..
=> ERROR [stage-0 5/6] RUN composer global require hirak/prestissimo 1.2s
------
> [stage-0 5/6] RUN composer global require hirak/prestissimo:
#9 0.300 Changed current directory to /composer
#9 1.195
#9 1.199
#9 1.199 [RuntimeException]
#9 1.199 No composer.json present in the current directory (./composer.json), this may be the cause of the following exception.
#9 1.199
#9 1.199
#9 1.201
#9 1.201 [InvalidArgumentException]
#9 1.201 Could not find package hirak/prestissimo.
#9 1.201
#9 1.201 Did you mean this?
#9 1.201 hirak/prestissimo
#9 1.201
#9 1.201
#9 1.201 require [--dev] [--dry-run] [--prefer-source] [--prefer-dist] [--fixed] [--no-suggest] [--no-progress] [--no-update] [--no-install] [--no-scripts] [--update-no-dev] [-w|--update-with-dependencies] [-W|--update-with-all-dependencies] [--with-dependencies] [--with-all-dependencies] [--ignore-platform-req IGNORE-PLATFORM-REQ] [--ignore-platform-reqs] [--prefer-stable] [--prefer-lowest] [--sort-packages] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--apcu-autoloader] [--apcu-autoloader-prefix APCU-AUTOLOADER-PREFIX] [--] [<packages>]...
#9 1.201
------
executor failed running [/bin/sh -c composer global require hirak/prestissimo]: exit code: 1
原因
タグの指定
ぱっと見、前述した hirak/prestissimo
がない見つからないというエラーです。
噛み砕いていくと --from=composer
では、タグによるバージョン指定を行なっていません。デフォルトだと latest
というタグが Docker Hub より pull されるため、今回 composer:latest
すなわち 2 系の公式 composer イメージが docker pull されていました。(PHP では指定しているのに・・・。)
Composer v2
composer 2 系でのアップデートで劇的にパフォーマンスが改善されました。ここでも詳細は割愛します。下記の記事に分かりやすくまとめてありました。
ここでのポイントとしては、composer v2 では、パッケージの並列インストールが可能になったということです。すなわち hirak/prestissimo
をインストールする必要がなくなりました。(composer v2 には未対応。)
対処方法
対処する方法としては 2 つ考えられます。
1. composer v2 にアップグレード
単純に composer v2 にしてしまうという方法です。その場合は Dockerfile で hirak/prestissimo
をインストールしている箇所を削除しておきましょう。
また、今後のことも考えるとタグも明示的に指定してあげておくのが良いでしょう。
FROM php:7.4-fpm-alpine
COPY php.ini /usr/local/etc/php/
ARG TZ
- COPY /usr/bin/composer /usr/bin/composer
+ COPY /usr/bin/composer /usr/bin/composer
ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME /composer
RUN composer config -g repos.packagist composer https://packagist.jp
- RUN composer global require hirak/prestissimo
RUN docker-php-ext-install pdo_mysql opcache
2. Docker イメージにタグを明示的に指定
composer v2 に気軽にアップグレードしてしまうのが怖い場合は、対処方法 1. のうちタグの指定だけ行うという方法です。もしかしたら依存関係により動かなくなってしまう可能性もあるので 1 系で固定してしまうのも応急処置としてはありではないでしょうか。
COPY /usr/bin/composer /usr/bin/composer
まとめ
最後に本記事のまとめを書いて終わります。
- Dockerfile の FROM 命令ではタグを明示的に指定するのを忘れない。
- composer は 2 系を積極的に導入していきたい。
-
hirak/prestissimo
はとても優秀なライブラリ。1 系を使うなら導入必須。
参考にさせていただいたサイト
Discussion