開発ブログ

株式会社Nextatのスタッフがお送りする技術コラムメインのブログ。

電話でのお問合わせ 075-744-6842 ([月]-[金] 10:00〜17:00)

  1. top >
  2. 開発ブログ >
  3. PHP >
  4. Laravel >
  5. AWS CodeBuild + Cloud Native BuildpacksでLaravelアプリのイメージをビルドし、App Runnerにデプロイする

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にプライベートレポジトリを作成します。

laravel-app-runner-ecr.png

CodeBuild設定

今回はAmazon ECRへのコンテナイメージのPushを行うのみで、特に多段の処理は行いません。 AWSブログの例のようにCodePipelineは利用せず、CodeBuildを直接利用することにします。

ソースプロバイダはGitHub、リポジトリはGitHubアカウントのリポジトリを選んで、OAuthでGitHubに接続し、先ほど作成したGitHubリポジトリを指定します。

https://github.com/{GITHUB_ACCOUNT_NAME}/laravel-app-runner-test.git

プライマリソースのウェブフックイベントのセクションで コードの変更がこのレポジトリにプッシュされるたびに再構築する にチェックを入れておきます。

laravel-app-runner-codebuild1.png
 

環境はマネージド型イメージでOS:Ubuntu、ランタイム:スタンダード、イメージ:aws/codebuild/standard:5.0を指定し、特権付与の項目にチェックを入れます。 サービスロールは新規作成としておきます。

laravel-app-runner-codebuild2.png

作成されたCodeBuildのプロジェクトは下記のようになります。

laravel-app-runner-codebuild3.png

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
 

laravel-app-runner-iam.png

リソースは先ほど作成した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のリポジトリにイメージが保存されていることを確認できます。

laravel-app-runner-ecr2.png

App Runner

App Runnerの管理画面で サービスを作成 をクリックします。

ステップ1ではソースには先ほど作成したECRのリポジトリを指定し、デプロイトリガーは自動としておきます。

laravel-app-runner-app-runner1.png

ステップ2のサービス設定ではサービス名を入力し、環境変数を指定します。

APP_KEYはローカル環境で生成されているはずなので.envのAPP_KEYの値をコピー&ペーストしてください。 LOG_CHANNELの値をstderrにして、標準エラー出力にログが出力されるようにしておくとデバッグしやすくなります。

また、今回は試しにデプロイしてみるだけなので、Auto Scalingはカスタム設定で最大サイズを1とし、スケーリングしないようにしておきましょう。 その他はデフォルト値のままです。

laravel-app-runner-app-runner2.png

ステップ3で設定項目を確認し、サービス作成を実行します。

初回のデプロイまで時間がかかるのでしばらく待ちます。 「Create serviceが成功しました。」という通知が表示されたら、デフォルトドメインに表示されているURLにアクセスします。

laravel-app-runner-laravel-on-app-runner.png

見事、LaravelのWelcomeページが表示されることが確認できました。

まとめ

Cloud Native Buildpacksを利用してLaravelアプリケーションをCodeBuildとECRを経由でApp Runnerにデプロイする仕組みを構築しました。 IAMのECRの権限周り以外はすんなりと設定できる単純な構成だと思います。

今回の構成はデータベースには接続できていないためまだ実用的ではありませんが、App RunnerからRDSやAurora Serverlessに接続するのは難しくありません。

App Runnerは今の所はアクセスがない状態でも料金がかかるため、不要になったApp Runnerのサービスは削除しておくのをお忘れなく。

TOPに戻る