AWS CodeBuild + Cloud Native BuildpacksでLaravelアプリのイメージをビルドし、App Runnerにデプロイする
こんにちは、ナカエです。
本日は 以前の記事 で紹介した Cloud Native Buildpacks を活用する記事の第四弾です。 今回はGCPではなくAWSでCNBを利用する方法をお届けします。
AWSのブログ記事として投稿されていた、Cloud Native Buildpacks による AWS CodeBuild と AWS CodePipeline を使ったコンテナイメージの作成 を参考にして進めていきます。
検証環境とソフトウェアのバージョン
- OS: macOS Monterey 12.2.1
- CPU: Intel Core i5
- zsh 5.8
- pack 0.25.0
- PHP 8.1.5
- Laravel 9.10.1
Laravelアプリを作成
下記コマンドで新規Laravelアプリを作成し、
composer create-project laravel/laravel laravel-app-runner-test
初期状態をコミットしておきます。
cd laravel-app-runner-test
git init
git add .
git commit -m "first commit"
Cloud Native Buildpacks向けのイメージビルド設定
作成・変更するファイルは 以前のCloud Native Buildpacksの記事 とほぼ同じで、HerokuのBuildpackを利用します。
Procfile
web: heroku-php-nginx -C nginx.conf public
nginx.conf
location / {
try_files $uri @rewriteapp;
}
location @rewriteapp {
rewrite ^(.*)$ /index.php$1 last;
}
project.toml
[project]
id = "laravel-app-runner-test"
name = "Laravel App Runner Test"
version = "1.0.0"
[build]
exclude = [
"/README.md",
"/.git",
"/vendor",
"/node_modules"
]
builder = "heroku/buildpacks:20"
[[build.buildpacks]]
uri = "heroku/php"
[[build.buildpacks]]
uri = "heroku/procfile@1.0.1"
[[build.buildpacks]]
uri = "heroku/nodejs"
package.json
{
"name": "laravel-app-runner-test",
"private": true,
"engines": {
"node": "16.x"
},
"scripts": {
// 略
"heroku-postbuild": "npm run production"
},
// 略
}
AWS CodeBuild用のビルド設定ファイルを作成
pack CLIでビルドしたイメージをECRにpushするという内容で buildspec.yml を作成します。
ほとんど参考にしたAWSのブログ記事からの拝借ですが、builderの指定はproject.tomlで行っているため省略しています。 Pack CLIをダウンロードしてきてpack buildを実行し、そのままECRへとpushするという内容です。
version: 0.2
env:
variables:
APPLICATION_NAME: "laravel-app-runner-test"
PACK_VERSION: "0.25.0"
phases:
install:
commands:
- wget -q https://github.com/buildpacks/pack/releases/download/v$PACK_VERSION/pack-v$PACK_VERSION-linux.tgz -O - | tar -xz
- chmod +x ./pack
pre_build:
commands:
- AWS_ACCOUNT_ID=$CODEBUILD_BUILD_ARN && IFS=':' && set -- $AWS_ACCOUNT_ID && AWS_ACCOUNT_ID=$5
- ECR_DOMAIN="$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com"
- ECR_REPOSITORY="$ECR_DOMAIN/$APPLICATION_NAME"
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ECR_DOMAIN
build:
commands:
- |
./pack build "$ECR_REPOSITORY:latest" \
--verbose \
--no-color \
--cache-image "$ECR_REPOSITORY:cache" \
--tag "$ECR_REPOSITORY:$CODEBUILD_RESOLVED_SOURCE_VERSION" \
--publish
変更をコミットします。
git add .
git commit -m "add build settings."
GitHubのリポジトリを作成
laravel-app-runner-test という名前でプライベートリポジトリを作成し、ここまでの内容をpushします。
※ 以下、{GITHUB_ACCOUNT_NAME} は自身のアカウント名で置き換えてください
git remote add origin https://github.com/{GITHUB_ACCOUNT_NAME}/laravel-app-runner-test.git
git push -u origin main
Amazon ECRにリポジトリを作成
laravel-app-runner-testという名前でECRにプライベートレポジトリを作成します。
CodeBuild設定
今回はAmazon ECRへのコンテナイメージのPushを行うのみで、特に多段の処理は行いません。 AWSブログの例のようにCodePipelineは利用せず、CodeBuildを直接利用することにします。
ソースプロバイダはGitHub、リポジトリはGitHubアカウントのリポジトリを選んで、OAuthでGitHubに接続し、先ほど作成したGitHubリポジトリを指定します。
https://github.com/{GITHUB_ACCOUNT_NAME}/laravel-app-runner-test.git
プライマリソースのウェブフックイベントのセクションで コードの変更がこのレポジトリにプッシュされるたびに再構築する
にチェックを入れておきます。
環境はマネージド型イメージでOS:Ubuntu、ランタイム:スタンダード、イメージ:aws/codebuild/standard:5.0を指定し、特権付与の項目にチェックを入れます。 サービスロールは新規作成としておきます。
作成されたCodeBuildのプロジェクトは下記のようになります。
CodeBuild用のロールに権限を追加
CodeBuildのプロジェクト作成と共に、codebuild-laravel-app-runner-test-service-role
というロールとそのロールに設定された CodeBuildBasePolicy-laravel-app-runner-test-ap-northeast-1
という名称のポリシーが作成されています。
デフォルトのままだとECRを操作する権限が足りないのでポリシーに権限を追加します。
ポリシーの編集画面でElastic Container Registryの下記権限を追加で選択し、
- BatchCheckLayerAvailability
- BatchGetImage
- GetAuthorizationToken
- GetDownloadUrlForLayer
- CompleteLayerUpload
- InitiateLayerUpload
- PutImage
- UploadLayerPart
リソースは先ほど作成したECRのリポジトリを指定しておきます。
arn:aws:ecr:{AWS_REGION}:{AWS_ACCOUNT_ID}:repository/laravel-app-runner-test
※ {AWS_REGION} と {AWS_ACCOUNT_ID} は適宜置き換え
ビルドをトリガーする
空でコミットを作成してCodeBuildのビルドをトリガーします。
git commit --allow-empty -m "trigger CodeBuild"
git push origin main
CodeBuildのビルドプロジェクト詳細画面をリロードすれば、ビルド履歴に実行中のビルドが表示されます。 ビルドが成功したら、ECRのリポジトリにイメージが保存されていることを確認できます。
App Runner
App Runnerの管理画面で サービスを作成
をクリックします。
ステップ1ではソースには先ほど作成したECRのリポジトリを指定し、デプロイトリガーは自動としておきます。
ステップ2のサービス設定ではサービス名を入力し、環境変数を指定します。
APP_KEYはローカル環境で生成されているはずなので.envのAPP_KEYの値をコピー&ペーストしてください。 LOG_CHANNELの値をstderrにして、標準エラー出力にログが出力されるようにしておくとデバッグしやすくなります。
また、今回は試しにデプロイしてみるだけなので、Auto Scalingはカスタム設定で最大サイズを1とし、スケーリングしないようにしておきましょう。 その他はデフォルト値のままです。
ステップ3で設定項目を確認し、サービス作成を実行します。
初回のデプロイまで時間がかかるのでしばらく待ちます。 「Create serviceが成功しました。」という通知が表示されたら、デフォルトドメインに表示されているURLにアクセスします。
見事、LaravelのWelcomeページが表示されることが確認できました。
まとめ
Cloud Native Buildpacksを利用してLaravelアプリケーションをCodeBuildとECRを経由でApp Runnerにデプロイする仕組みを構築しました。 IAMのECRの権限周り以外はすんなりと設定できる単純な構成だと思います。
今回の構成はデータベースには接続できていないためまだ実用的ではありませんが、App RunnerからRDSやAurora Serverlessに接続するのは難しくありません。
App Runnerは今の所はアクセスがない状態でも料金がかかるため、不要になったApp Runnerのサービスは削除しておくのをお忘れなく。
- PHP , AWS , Buildpacks , CNCF , コンテナ , App Runner , CodeBuild