トップ画像
LaravelをCloud Runにデプロイして効率よくバックエンドを開発しよう!

執筆者: sasigume

最終更新: 11/11/2021

何円ぐらいで済むの?




以下の手順で60.77時間、動かしてみました。リージョンは全て東京(asia-northeast1)です。

結果

  • MySQL 実行: 97円
  • MySQL ストレージ: 11円
  • ストレージ(NA-APAC間の通信): 5円

以上、113円でした。

一時間1.85円として計算すると、1ヶ月で1338円になります。

お詫び

すいません、ケチれませんでした!!!!!

ただ、GitHubからデプロイすることで

  • 効率の良い開発
  • スケール
  • 他GCPサービスとの円滑な連携

が可能になる点は見逃せません。余裕のある方は試してみてください。

下準備

GCPのセットアップ

gcloud CLIをインストールしておく。環境によって手順が異なるので省略。

プロジェクトを作り、支払いアカウントを紐づける。

gcloud auth login

まずはログインする。

PROJECT_NAME=(表示上のプロジェクトネーム)
PROJECT_ID=$(gcloud projects list --format 'value(projectId)' --filter name=$PROJECT_NAME)
export PROJECT_ID
gcloud config set project $PROJECT_ID
gcloud services enable \
    containerregistry.googleapis.com \
    cloudresourcemanager.googleapis.com \
    iam.googleapis.com

「表示上のプロジェクトネーム」はGCPの画面に出ているプロジェクト名。プロジェクトをセットし、APIを有効化する。

Terraformのインストール

いつか使うんだろうなーと思っていた。入れてなかったのでここで入れておく。

brew install tfenv
tfenv install 0.12.6
tfenv use 0.12.6

tfenvを使うのは、以下のテンプレートが0.12.6を想定していたから。随時変更しよう。

ステップ1. テンプレートを準備

自分でやろうとしたがあまりにめんどくさかったので、以下のテンプレートを使う。

https://github.com/villers/laravel-cloud-run-sql

これをフォークしよう。

クローンしてビルド

git clone git@github.com:あなたのユーザー名/laravel-cloud-run-sql.git
cd laravel-cloud-run-sql
docker-compose build


euをasiaに

東京で動かすので、レポジトリ内のeu.gcr.ioasia.gcr.io に置換。

ローカルで試す

docker-compose up


起動の様子。なんでもDockerでやれば、なんかすごいことやってるみたいに見える。

docker-compose run --rm app php artisan migrate --seed


マイグレーションする。



http://localhost:8080/ で動作確認しよう。

ステップ2. GCPにコンテナをアップする

サービスアカウントを用意する

サービスアカウントを作り、Owner権限を与える。キーをダウンロードしてterraform-key.json として保存し、環境変数に設定、サービスアカウントとして認証する。それらが以下のコマンドでできる。ありがとうgcloud CLI!

gcloud iam service-accounts create deployer \
    --display-name "Terraformのサービスアカウント"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member serviceAccount:deployer@${PROJECT_ID}.iam.gserviceaccount.com \
  --role roles/owner
gcloud iam service-accounts keys create ~/terraform-key.json \
  --iam-account deployer@${PROJECT_ID}.iam.gserviceaccount.com
export GOOGLE_APPLICATION_CREDENTIALS=~/terraform-key.json
gcloud auth activate-service-account --key-file=$GOOGLE_APPLICATION_CREDENTIALS


ビルド(M1注意)

export SERVICE_NAME=laravel-app-service
docker build --platform linux/amd64 -f .cloud/docker/php/Dockerfile -t asia.gcr.io/${PROJECT_ID}/${SERVICE_NAME} .


上記コマンドでアジア用タグをつけたイメージをビルドする。間違ったタグをつけたりしたら、docker images からのdocker rmi [ID] で消せる。それか、Docker Desktopのイメージ画面を使う。

--platform linux/amd64 はM1用。ARMでビルドしてもデプロイで死ぬ。このせいで数時間が無駄になった。

レジストリにプッシュ

gcloud auth configure-docker
docker push asia.gcr.io/${PROJECT_ID}/${SERVICE_NAME}

コンテナレジストリにログインして、さっきのをプッシュする。

ステップ3. 自動でCloud SQLとLaravelをデプロイ

Terraform初期化

cd .cloud/terraform
terraform init


ついに初回デプロイ

export REGION=asia-northeast1
export INSTANCE_NAME=laravel-app-service
terraform apply \
  -var "region=${REGION}" \
  -var "service=${SERVICE_NAME}" \
  -var "project=${PROJECT_ID}" \
  -var "instance_name=${INSTANCE_NAME}"


Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value:


yesと打てば、

  • Secret Managerでキーを作り
  • `laravel`というサービスアカウントができ
  • Cloud SQLにMySQLをセットアップ
  • Cloud RunでLaravelをデプロイ

の4つが行われる。


Cloud SQLの部分でかなり時間がかかる。

Apply complete! Resources: 26 added, 0 changed, 0 destroyed.

Outputs:

result =     The laravel-app-service is now running at https://<ここにURL>
    If you haven't deployed this service before, you will need to perform the initial database migrations:
    cd ../..
    gcloud builds submit --project <ここにプロジェクトID> --config .cloudbuild/build-migrate-deploy.yaml \
        --substitutions _APP_ENV=dev,_APP_DEBUG=true,_REGION=asia-northeast1,_INSTANCE_NAME=laravel-app-service,_SERVICE=laravel-app-service

    The username and password are stored in these secrets:
    gcloud secrets versions access latest --secret DATABASE_URL
    ✨


終わるとこんなんが出てくる。



Cloud Runの画面でもURLが確認できる。マイグレーションは後でやる。

GitHubと連動してビルド・デプロイさせる

実はTerraformを使うのは初回だけでいい。あとはCloud Buildを活用しよう。

ルートにcloudbuild.yaml を作る。

cloudbuild.yaml

steps:
  - id: 'build_and_push'
    name: 'gcr.io/kaniko-project/executor:latest'
    args:
      [
        # https://github.com/GoogleContainerTools/kaniko/issues/1427
        "--dockerfile=.cloud/docker/php/Dockerfile",
        "--cache=true",
        "--cache-ttl=6h",
        "--destination=asia.gcr.io/${PROJECT_ID}/${_SERVICE}",
      ]
  
  - id: 'migrate'
    name: 'gcr.io/google-appengine/exec-wrapper'
    args: ['-i', 'asia.gcr.io/${PROJECT_ID}/${_SERVICE}',
           '-s', '${PROJECT_ID}:${_REGION}:${_INSTANCE_NAME}',
           '-e', 'PROJECT_ID=${PROJECT_ID}',
           '-e', 'APP_ENV=${_APP_ENV}',
           '-e', 'APP_DEBUG=${_APP_DEBUG}',
           '--', 'php', 'artisan', 'migrate']

  - id: 'deploy'
    name: 'gcr.io/cloud-builders/gcloud'
    args: ["run", "deploy", "${_SERVICE}",
           "--platform", "managed",
           "--region", "${_REGION}",
           "--image", "asia.gcr.io/$PROJECT_ID/${_SERVICE}"]

options:
  substitutionOption: ALLOW_LOOSE
substitutions:
  _APP_ENV: prod
  _APP_DEBUG: "false"
  _SERVICE: laravel-app-service
  _REGION: asia-northeast1
  _INSTANCE_NAME: laravel-app-service


ビルドのトリガー設定を変更(重要)


次に、Cloud Runのページを開く。



このボタンでビルドのトリガーを作れる。

GitHubのレポジトリと接続すればいいが、Dockerfile は間違いなので修正が必要。


「EDIT CONTINUOUS DEPLOYMENT」から設定を開き、LocationRepository に変える。 Cloud Build configuration file (yaml or json) を選択する。/cloudbuild.yaml になっているか確認。ブランチ名を変えた場合は、適宜トリガーの設定も変える。


プッシュすればビルド、プッシュ、マイグレーション、デプロイがされる。こちらのリンクからビルド履歴が見れる。


初回は時間がかかるが...


2回目以降はKanikoがキャッシュを活用してくれる。大体二分で終わる。

え? FTPで差分をアップした方が早い? 確かにそうかもしれない。だが、

  • 全部自動化
  • バージョンを戻せる
  • 環境を簡単に再現

という点で明らかに効率がいい。積極的に活用していこう。

取得に失敗しました

2021年度 入部

Twitter GitHub YouTube