AWS CodeBuildでcomposer installしたライブラリをキャッシュする
はじめに
Code兄弟のCodePipeline,CodeBuild,CodeDeployを利用してCI/CD環境を構築した際(ソースはBitBucket)に、
composer installしたライブラリをキャッシュする方法の記事がなく時間がかかったため作成します。
なぜキャッシュをするのか
キャッシュをすることによりデプロイに、要する時間を短縮できるためサービスを早く提供することができるメリットがあります。
小規模なインフラ構成の場合は多少の時間しか短縮できませんが、少しでも短い方が良いと思うので是非参考にしていただければと思います。
CodeBuildのキャッシュ機能
CodeBuildのキャッシュ機能は2通りあります
- S3キャッシュ
- 複数のビルドホスト間で利用できるキャッシュ
- ダウンロードするよりも構築にコストがかかる小規模な中間ビルドアーティファクトに適したオプション
- ネットワーク経由で転送するには長い時間がかかる場合があるため、大規模なビルドアーティファクトには適していません
- Docker レイヤーを使用する場合、これは最適なオプションではありません。
- ローカルキャッシュ(buildを実行するホストに保存する)
- ビルドホストのみが利用できるキャッシュをそのビルドホストにローカルに保存します
- キャッシュはビルドホストですぐに利用できるため、この方法は大規模な中間ビルドアーティファクトに適しています
- ビルドホストのみが利用できるキャッシュをそのビルドホストにローカルに保存します
AWS公式記事「AWS CodeBuild でのキャッシュのビルド」
ローカルキャッシュはキャッシュモードが3つある
キャッシュする内容を選ぶことができる、キャッシュモードが3つあります。
- ソースキャッシュモード
- Docker レイヤーキャッシュモード
- カスタムキャッシュモード
それぞれの内容は公式記事を参照してください。
今回私のケースは以下
- 小規模なアプリ
- dockerを使用
- ビルドホストは1つ
せっかくなので実行の比較をしてみましょう。(composerのキャッシュの)
ローカルキャッシュとS3キャッシュの実行時間の比較
それぞれの設定で2回実行し、2回目の実行時間を比較します。
ローカルキャッシュに関しては、カスタムキャッシュモード
を使用してみます。
buildspecファイルを作成する際にcacheを利用するようにする
codebuildを使用する際は、buildspecファイルを作成する必要があります。
そのファイルの記述の中で、キャッシュを利用することを記述する箇所があるため、そこにcompopserのcacheディレクトリを指定することで、
実現することができます。
つまづいたポイント1
composer install
をdockerファイル内で実行していると、コンテナ内にcompoesrのキャッシュファイルができるため、
キャッシュすることができなかった。
解決する方法としては
- ホスト側で
composer install
する。 - ホスト側とコンテナ側で依存ライブラリのディレクトリをマウントして同期させる
今回は1の方法を取りたいと思います。
buildspecファイルの内容は以下になります。
version: 0.2
phases:
install:
## ここでphpの実行環境のバージョンを指定する
runtime-versions:
php: 7.3
pre_build:
commands:
- $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)
- IMAGE_TAG=$CODEBUILD_RESOLVED_SOURCE_VERSION
- REPOSITORY_URI=********.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/restful-api
build:
commands:
## ホスト側でcomposer install
- composer install
- docker build -t $REPOSITORY_URI:$IMAGE_TAG .
- docker push $REPOSITORY_URI:$IMAGE_TAG
post_build:
commands:
- echo Writing image definitions file...
- printf '[{"name":"restful-api", "imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imageDetail.json
artifacts:
files:
- imageDetail.json
## ここがキャッシュを指定する箇所!!!!
cache:
paths:
- '/root/.composer/**/*'
注目していただきたいのはcache
項目になります。
つまづきポイント2
実際にbuild実行したところ、2回以上build実行しても、キャッシュが利用されている形跡がなく実行時間も短くなりません。
ローカルキャッシュのカスタムキャッシュ
は先ほどのbuild.specのままではdockerでは使えないという問題がわかりました。
原因は、以下の実行時のログを見ると気付きました。
Symlinking: /root/.composer => /codebuild/local-cache/custom/a29cac2ab2bc5a9ecb43317ff3dd8847f93bf828b0606fda90fa7db63d27cebb/root/.composer
ローカルキャッシュのカスタムキャッシュの仕組みはキャッシュ対象のパスから、codebuildのキャッシュ用ディレクトリ(?)に対して、Symlinkを貼るという内容でした。
dockerではホスト・コンテナ間でのSymlinkはサポートしていないため、キャッシュが取れませんでした。(この事実を知るのに、かなり時間がかかったのに。。。)
どうやって実現できるのかというと
大変参考になる方法を見つけたので、(参考記事「AWS CodeBuildのローカルキャッシュのCustom cacheでnode_modulesやvendorをキャッシュする
」)[https://tech.moyashidaisuke.com/entry/2019/03/19/205243]に対応方法を真似することにしました。
version: 0.2
phases:
install:
## ここでphpの実行環境のバージョンを指定する
runtime-versions:
php: 7.3
pre_build:
commands:
- $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)
- IMAGE_TAG=$CODEBUILD_RESOLVED_SOURCE_VERSION
- REPOSITORY_URI=********.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/restful-api
## キャッシュを利用する
- cp -r /root/.composer_cache/ /root/.composer/
build:
commands:
- composer install
- docker build -t $REPOSITORY_URI:$IMAGE_TAG .
- docker push $REPOSITORY_URI:$IMAGE_TAG
post_build:
commands:
- echo Writing image definitions file...
- printf '[{"name":"restful-api", "imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imageDetail.json
## 最新のキャッシュファイルをローカルキャッシュ用ディレクトリにコピーする
- cp -r /root/.composer/ /root/.composer_cache/
artifacts:
files:
- imageDetail.json
cache:
paths:
- '/root/.composer/**/*'
やっていることは、
1. カスタムキャッシュしたローカルキャッシュ用ディレクトリをキャッシュ利用したかったディレクトリにコピーする
2. build後に最新のキャッシュをローカルキャッシュ用ディレクトリにコピーしてあげる
実行結果
今回のケースでいうとS3キャッシュを利用する方が早く終わりました。
備考(インフラ構成図)
色々使用しておりますが、今回関係のある箇所は赤枠で囲われた部分になります。
CodePipeline,CodeBuild,CodeDeployを使用してECSにデプロイをしております。
最後に
今回のS3とカスタムキャッシュで、composerのキャッシュを利用した場合、S3の方が早かったですが、ローカルキャッシュは他にも2つのキャッシュモードがあるため、それを合わせて利用すれば早くなりそうです。(実際に試したが、Docker レイヤーキャッシュモードがキャッシュ利用できなかったので、今度調べてみようと思います。)
Author And Source
この問題について(AWS CodeBuildでcomposer installしたライブラリをキャッシュする), 我々は、より多くの情報をここで見つけました https://qiita.com/bellcrud/items/ed402253a2f9b2e39fa7著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .