Cloud Native BuildpacksでビルドしたLaravelアプリのイメージをCloud Runにデプロイする
こんにちは、ナカエです。 本日は 以前の記事 で紹介した Cloud Native Buildpacks(CNB) を活用する記事の第二弾です。最近流行りのGoogle Cloud PlatformのCloud Runと組み合わせる方法を検証します。
より具体的には、Cloud RunへのLaravelアプリケーションのデプロイ時に、CNBでビルドしたイメージを使うにはどうするかという内容です。
検証環境とソフトウェアのバージョン
- OS: macOS Monterey 12.3
- CPU: Apple M1 Max
- zsh 5.8
- Homebrew 3.4.5
- Google Cloud SDK 380.0.0
- Docker Desktop for Mac 4.6.1
- Pack 0.24.1
- PHP 8.1.4
- Laravel 9.7.0
Google Cloud Platformのプロジェクト作成
- Identity and Access Management (IAM) API
- Container Registry API
- Cloud Build API
- Cloud Run API
を有効化しておきます。
Google Cloud SDKのインストールと設定
Google Cloud SDKはGoogle Cloud Platformをコマンドラインから操作するためのツールです。以降の作業で必要になるので最初にインストールしておきます。
Homebrew経由でインストールします。
brew install --cask google-cloud-sdk
参考: Google Cloud SDK(gcloud) を Homebrew 経由で Mac にインストールする方法
~/.zshrc に 下記を追加し、パスを通しておきます。
# Google Cloud SDK
source /usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/path.zsh.inc
シェルを読み込み直し、初期化コマンドを実行します。
gcloud init
開いたブラウザの画面でログインすると認可画面が表示されるので、Google Cloud SDKへのアクセス許可を承認してください。
あとは指示に従って、利用するプロジェクトの選択などを行います。
Laravelアプリを作成
続いてLaravelアプリの作成です。Laravelアプリの作成方法は色々とありますが、今回はbashでスクリプト実行するだけでLaravel Sail環境までを自動でセットアップしてくれる方法を利用します。
参考: Getting Started On macOS - Installation - Laravel - The PHP Framework For Web Artisans
作業用のディレクトリに移動し下記コマンドを打つとセットアップが始まります。
curl -s "https://laravel.build/laravel-cloud-run-test" | bash
セットアップが完了したら、Sailを起動します
cd laravel-cloud-run-test
./vendor/bin/sail up
ブラウザで http://localhost にアクセスすると、Laravelのホーム画面が表示されます。
一度、この状態をコミットしておきましょう。
git init
git add .
git commit -m "first commit"
Cloud Source RepositoriesでGitリポジトリを作成
今回はGitHubなどは使わずGCP内で完結させることにしたので、Cloud Source Repositoriesを利用します。
新しいGitリポジトリを laravel-cloud-run-test という名前で作成します。
ローカルマシンからpushできるように設定も済ませておきましょう。
※ {projectId}や{repoName}は設定に合わせて適宜置き換えてください。
git config --global credential.'https://source.developers.google.com'.helper gcloud.sh
git remote add origin https://source.developers.google.com/p/{projectId}/r/{repoName}
git push -u origin main
packコマンドのコンテナイメージを登録
Cloud Runで利用するコンテナイメージの作成にはCloud Native Buildpacksを利用します。
Google Cloud Buildpacks
GCPは Google Cloud Buildpacks というCNBに対応した仕組みを備えており、コンテナイメージの自動生成が可能です。
現時点では
- Go 1.10+
- Node.js 10+
- Python3.7+
- Java 8+
- .NET Core 3.1+
- Ruby 2.6+
のランタイムに対応していますが、
誠に残念ながらPHPには対応していません。
代替策
そこで、packコマンドを実行するコンテナイメージをContainer Registryに登録し、Cloud Buildから利用することにします。
コミュニティ主導でGoogle Cloud Build用のDockerfileを配布しているGitHubリポジトリがあるのでこちらを利用します。
GoogleCloudPlatform/cloud-builders-community: Community-contributed images for Google Cloud Build
cd ../
git clone https://github.com/GoogleCloudPlatform/cloud-builders-community
cd cloud-builders-community
cd pack
デフォルトではpackコマンドのバージョンが随分と古いので、DockerfileのENVを変更する必要がありました。
cloud-builders-community/pack/Dockerfile
FROM busybox
- ENV PACK_VERSION=v0.11.0
+ ENV PACK_VERSION=v0.24.1
RUN wget -O- https://github.com/buildpacks/pack/releases/download/${PACK_VERSION}/pack-${PACK_VERSION}-linux.tgz | tar zx
FROM gcr.io/distroless/base
ENTRYPOINT ["/pack"]
COPY --from=0 /pack /
この状態でイメージをビルドし、
docker build ./ -t gcr.io/{projectId}/pack
Dockerコマンドが利用する認証情報を設定します。
gcloud auth configure-docker
これで作成したGCPプロジェクトのContainer Registryにイメージをpushできるようになりました。
docker push gcr.io/laravel-cloud-run-test/pack
pushが成功すると、GCP管理画面のContainer Registryのイメージ一覧にpackが表示されることを確認できます。
Cloud Native Buildpacks向けのイメージビルド設定
Laraelプロジェクトに戻って作業します。
cd ../
cd laravel-cloud-run-test
作成・変更するファイルは 以前の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-cloud-run-test"
name = "Laravel Cloud Run Test"
version = "1.0.0"
[build]
exclude = [
"/README.md",
".git"
]
[[build.buildpacks]]
uri = "heroku/php"
[[build.buildpacks]]
uri = "heroku/procfile@1.0.1"
[[build.buildpacks]]
uri = "heroku/nodejs"
package.json
{
"name": "laravel-cloud-run-test",
// 略
"scripts": {
// 略
"heroku-postbuild": "npm run production"
},
// 略
}
Cloud Buildの設定
ビルド構成ファイル作成
Laravelプロジェクトの直下にcloudbuild.yaml を作成します。
steps:
- name: gcr.io/$PROJECT_ID/pack
args:
- build
- --builder
- heroku/buildpacks:20
- gcr.io/$PROJECT_ID/myapp:$REVISION_ID
- --publish
- name: gcr.io/cloud-builders/gcloud
id: cloud-run-deploy
args:
- run
- deploy
- myapp
- --image
- gcr.io/$PROJECT_ID/myapp:$REVISION_ID
- --region
- asia-northeast1
- --allow-unauthenticated
options:
logging: CLOUD_LOGGING_ONLY
Cloud Build用のサービスアカウント作成
トリガーを作成する前に、トリガーを実行するサービスアカウントを作成します。
大半は既存のロールで設定できるのですが、一つだけカスタムのロールが必要なので先に作ります。 タイトルは cloud-run-act-as とし iam.serviceAccounts.actAs の権限を割り当てます。
次にサービスアカウント本体を作成します。
サービスアカウントIDをcloud-buildとして、下記の4つのロールを追加します。
- Cloud Build サービスアカウント
- Cloud Run 管理者
- Container Registry サービスエージェント
- 先ほど作成した cloud-run-act-as
Cloud Build のトリガーを作成
Cloud Buildのダッシュボードからトリガーを新規作成します。
ソースのリポジトリを laravel-cloud-run-test 、ブランチをmainとしておきます。
サービスアカウントは先ほど作成した cloud-build@〜 を選択してくだい。
ビルド & デプロイ
ここまでのローカルのLaravelプロジェクトの変更をコミットしてリモートにpushします。
git add .
git commit -m "build configuration"
git push origin main
Cloud Buildがトリガーされると、Cloud Buildの管理画面からビルド履歴を閲覧できます。
ビルド時間が2〜3分程かかるのでビルドが終了するまで待ちます。
環境変数の設定
GCPの管理画面からCloud Runのページにアクセスするとmyappという名前でサービスが作成されているので名前をクリックして詳細画面を開きます。
まだ環境変数の設定ができていないため、今のままLaravelアプリケーションにアクセスしてもエラーが表示される状態です。
Cloud Runのサービスの詳細画面の上部の新しいリビジョンの編集とデプロイをクリックして新規リビジョンのデプロイ画面を開きます。
変数とシークレットのタブの環境変数を追加します。
APP_KEYはローカル環境で生成されているはずなので.envのAPP_KEYの値をコピー&ペーストしてください。
また、LOG_CHANNELの値をstdoutにして、標準出力にログが出力されるようにしておくとデバッグしやすくなります。
このリビジョンをすぐに利用するにチェックを入れたまま、デプロイボタンをクリックしてデプロイします。
動作確認
新しいリビジョンがデプロイされた後、Cloud Runのサービスの詳細の上部に表示されているURLをクリックしするとデプロイされたアプリケーションにアクセスできます。
まとめ
Cloud Native Buildpacksを利用してLaravelアプリケーションをCloud Build経由でCloud Runにデプロイする仕組みを構築しました。
コンテナベースのマネージドサービスを利用する上で、Cloud Native Buildpacksが役に立つことを確認できたと思います。
※ Cloud Run向けGoogle Cloud BuildpacksのPHP対応によってpackの自前管理が不要になり、さらにデプロイ設定が楽になることを祈っています。
なお、この記事で作成した構成ではCloud Runからのデータベース接続を設定していないのでまだ実用的ではありません。しかし、管理画面から簡単にリビジョンのロールバックやブルーグリーンデプロイやカナリアリリースができること、アクセスがない場合はゼロスケールすることなどCloud Runの強みは確認できます。