開発ブログ

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

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

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

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のプロジェクト作成

gcp-new-project.png

事前にGCPの管理画面で新規プロジェクトを作成し、

  • 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のホーム画面が表示されます。

laravel-on-local-sail.png

一度、この状態をコミットしておきましょう。

git init
git add .
git commit -m "first commit"

Cloud Source RepositoriesでGitリポジトリを作成

今回はGitHubなどは使わずGCP内で完結させることにしたので、Cloud Source Repositoriesを利用します。

新しいGitリポジトリを laravel-cloud-run-test という名前で作成します。

cloud-source-repository-laravel-cloud-run.png

ローカルマシンから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が表示されることを確認できます。

container-registry-pack.png

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 の権限を割り当てます。

cloud-build-act-as.png

次にサービスアカウント本体を作成します。

cloud-build-service-account.png

サービスアカウントIDをcloud-buildとして、下記の4つのロールを追加します。

  • Cloud Build サービスアカウント
  • Cloud Run 管理者
  • Container Registry サービスエージェント
  • 先ほど作成した cloud-run-act-as
 

cloud-build-service-account-roles.png

Cloud Build のトリガーを作成

Cloud Buildのダッシュボードからトリガーを新規作成します。

ソースのリポジトリを laravel-cloud-run-test 、ブランチをmainとしておきます。

cloud-build-trigger.png

サービスアカウントは先ほど作成した 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のサービスの詳細画面の上部の新しいリビジョンの編集とデプロイをクリックして新規リビジョンのデプロイ画面を開きます。

変数とシークレットのタブの環境変数を追加します。

cloud-run-env.png

APP_KEYはローカル環境で生成されているはずなので.envのAPP_KEYの値をコピー&ペーストしてください。

また、LOG_CHANNELの値をstdoutにして、標準出力にログが出力されるようにしておくとデバッグしやすくなります。

このリビジョンをすぐに利用するにチェックを入れたまま、デプロイボタンをクリックしてデプロイします。

動作確認

新しいリビジョンがデプロイされた後、Cloud Runのサービスの詳細の上部に表示されているURLをクリックしするとデプロイされたアプリケーションにアクセスできます。

laravel-on-cloud-run.png

まとめ

Cloud Native Buildpacksを利用してLaravelアプリケーションをCloud Build経由でCloud Runにデプロイする仕組みを構築しました。

コンテナベースのマネージドサービスを利用する上で、Cloud Native Buildpacksが役に立つことを確認できたと思います。

※ Cloud Run向けGoogle Cloud BuildpacksのPHP対応によってpackの自前管理が不要になり、さらにデプロイ設定が楽になることを祈っています。

なお、この記事で作成した構成ではCloud Runからのデータベース接続を設定していないのでまだ実用的ではありません。しかし、管理画面から簡単にリビジョンのロールバックやブルーグリーンデプロイやカナリアリリースができること、アクセスがない場合はゼロスケールすることなどCloud Runの強みは確認できます。

TOPに戻る