はじめに
- LaravelアプリをCroud Run + Cloud SQL 環境にデプロイします
- Github Actions により、main への push -> deploy の環境を構築します
デプロイまでの流れ
Cloud RunにLaravelアプリケーションをデプロイするには、大きく分けて以下のステップが必要です。
- 前提条件の確認: 必要なツールやアカウントが揃っているか確認します。
-
Laravelアプリケーションのコンテナ化:
Dockerfileを作成し、Laravelアプリケーションをコンテナイメージとしてビルドできるようにします。 - Cloud Runへのデプロイ: ビルドしたコンテナイメージをCloud Runにデプロイします。
- データベース(Cloud SQL)との接続: Cloud RunからCloud SQLに接続するための設定を行います。
- 環境変数の設定: アプリケーションキーやデータベースの認証情報などの環境変数を設定します。
- データベースマイグレーションの実行: データベースのテーブルを作成・更新します。
- 静的アセットの配信: CSSやJavaScript、画像などの静的ファイルを効率的に配信するための設定を行います。
それでは、各ステップを詳しく見ていきましょう。
1. 前提条件の確認
まず、以下のツールとアカウントが準備されていることを確認してください。
- Google Cloud Platform (GCP) アカウント: GCPのアカウントをお持ちでない場合は、こちらから作成してください。
- gcloud CLI: Google Cloudのコマンドラインツールです。インストールガイドを参考にインストールと初期設定を済ませてください。
- Docker: コンテナイメージをビルドするために必要です。公式サイトからインストールしてください。
- Laravelプロジェクト: デプロイするLaravelプロジェクトを用意してください。
2. Laravelアプリケーションのコンテナ化
LaravelアプリケーションをCloud Runで実行するには、まずコンテナイメージを作成する必要があります。プロジェクトのルートディレクトリに Dockerfile という名前のファイルを作成し、以下の内容を記述してください。
# ベースイメージとしてPHP 8.2のFPM版を使用
FROM php:8.2-fpm
# 必要なPHP拡張機能をインストール
RUN apt-get update && apt-get install -y \
libzip-dev \
unzip \
&& docker-php-ext-install pdo_mysql zip
# Composerをインストール
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Nginxをインストール
RUN apt-get install -y nginx
# Nginxの設定ファイルをコピー
COPY ./docker/nginx.conf /etc/nginx/sites-available/default
# アプリケーションのソースコードをコピー
WORKDIR /var/www/html
COPY . .
# Composerの依存関係をインストール
RUN composer install --no-dev --optimize-autoloader
# ファイルの所有権とパーミッションを設定
RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache
RUN chmod -R 775 /var/www/html/storage /var/www/html/bootstrap/cache
# エントリーポイントスクリプトをコピーして実行権限を付与
COPY ./docker/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
# ポート8080を公開
EXPOSE 8080
# コンテナ起動時に実行するコマンド
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
次に、プロジェクトのルートに .docker ディレクトリを作成し、その中に nginx.conf と entrypoint.sh を作成します。
.docker/nginx.conf:
server {
listen 8080;
server_name _;
root /var/www/html/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
.docker/entrypoint.sh:
#!/bin/sh
# PHP-FPMをバックグラウンドで起動
php-fpm &
# Nginxをフォアグラウンドで起動
nginx -g 'daemon off;'
3. Cloud Runへのデプロイ
Dockerfile の準備ができたら、いよいよCloud Runにデプロイします。ターミナルで以下のコマンドを実行してください。
gcloud run deploy [SERVICE_NAME] --source .
[SERVICE_NAME] は任意のサービス名に置き換えてください。このコマンドを実行すると、Cloud Buildが自動的にコンテナイメージをビルドし、Cloud Runにデプロイしてくれます。
4. データベース(Cloud SQL)との接続
次に、Cloud RunからCloud SQLに接続するための設定を行います。
- Cloud SQLインスタンスの作成: GCPコンソールでCloud SQLインスタンスを作成します。
- Cloud RunとCloud SQLの接続: Cloud Runのサービス設定画面で、「接続」タブからCloud SQLへの接続を追加します。
-
.envファイルの設定:
.envファイルのデータベース接続情報を以下のように設定します。
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=[DATABASE_NAME]
DB_USERNAME=[DATABASE_USER]
DB_PASSWORD=[DATABASE_PASSWORD]
DB_SOCKET=/cloudsql/[INSTANCE_CONNECTION_NAME]
[INSTANCE_CONNECTION_NAME] はCloud SQLインスタンスの接続名に置き換えてください。
5. 環境変数の設定
APP_KEY などの重要な環境変数は、Cloud Runのサービス設定画面の「変数とシークレット」タブから設定します。.env ファイルの内容を直接貼り付けるのではなく、必要な変数のみを個別に設定することをお勧めします。
APP_KEY
DB_DATABASE
DB_SOCKET
DB_PASSWORD
DB_USERNAME
LOG_CHANNEL
DB_CONNECTION
6. データベースマイグレーションの実行
デプロイ後にデータベースのマイグレーションを実行するには、いくつかの方法があります。
-
Cloud Buildを使用する方法:
cloudbuild.yamlファイルにマイグレーションを実行するステップを追加することで、デプロイ時に自動でマイグレーションを実行できます。 - Cloud Run Jobsを使用する方法: マイグレーション用のCloud Run Jobを作成し、必要な時に手動またはスケジュールで実行します。
-
ローカルから実行する方法: ローカル環境からCloud SQL Proxyを使用してデータベースに接続し、
php artisan migrateコマンドを実行します。
ローカルからCloud SQLのDBに接続し、Laravelのマイグレーションを実行する #PHP - Qiita
7. 静的アセットの配信
CSSやJavaScript、画像などの静的ファイルは、Cloud StorageとCloud CDNを使用して配信することで、パフォーマンスを向上させることができます。
- Cloud Storageバケットの作成: 静的ファイルを保存するためのCloud Storageバケットを作成します。
- Laravelの設定: Laravelのファイルシステム設定を変更し、静的ファイルをCloud Storageにアップロードできるようにします。
- Cloud CDNの設定: Cloud StorageバケットをオリジンとしてCloud CDNを設定し、コンテンツをキャッシュして高速に配信します。
CICD化作業
artifacts の作成
gcloud artifacts repositories create [REPOSITORY_NAME] \
--repository-format=docker \
--location=[REGION] \
--description="Laravel Application Repository"
github secret の作成
GCP_PROJECT_ID: ご自身の Google Cloud プロジェクト ID。
GCP_SA_KEY: 先ほどコピーしたサービスアカウントの JSON キーの内容を貼り付けます。
GCP_SQL_CONNECTION_NAME: Cloud SQL インスタンスの接続名(例: my-project:us-central1:my-instance)。
GithubActions の設定
- .github/workflows/deploy.yml
# .github/workflows/deploy.yml
name: Deploy Laravel to Cloud Run
# mainブランチにプッシュされたときにワークフローを実行
on:
push:
branches:
- main
# 環境変数を設定
env:
GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}
GCP_SERVICE_NAME: "livewire2" # Cloud Runのサービス名
GCP_REGION: "asia-northeast1" # Cloud RunとArtifact Registryのリージョン
GCP_ARTIFACT_REPOSITORY: "livewire2" # Artifact Registryのリポジトリ名
GCP_SQL_CONNECTION_NAME: ${{ secrets.GCP_SQL_CONNECTION_NAME }}
jobs:
deploy:
name: Build and Deploy
runs-on: ubuntu-latest
# Google Cloudへの認証
permissions:
contents: "read"
id-token: "write"
steps:
# 1. リポジトリのコードをチェックアウト
- name: Checkout code
uses: actions/checkout@v4
# 2. Google Cloudへの認証
- name: Authenticate to Google Cloud
id: auth
uses: "google-github-actions/auth@v2"
with:
credentials_json: "${{ secrets.GCP_SA_KEY }}"
# 3. gcloud CLIのセットアップ
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2
# 4. Docker認証の設定
- name: Configure Docker
run: gcloud auth configure-docker ${{ env.GCP_REGION }}-docker.pkg.dev
# 5. Dockerイメージのビルドとプッシュ
- name: Build and Push Docker image
run: |
# イメージ名を定義 (リージョン-docker.pkg.dev/プロジェクトID/リポジトリ名/サービス名:コミットSHA)
export IMAGE_NAME=${{ env.GCP_REGION }}-docker.pkg.dev/${{ env.GCP_PROJECT_ID }}/${{ env.GCP_ARTIFACT_REPOSITORY }}/${{ env.GCP_SERVICE_NAME }}:${{ github.sha }}
# Dockerイメージをビルド
docker build -t $IMAGE_NAME .
# Artifact Registryにイメージをプッシュ
docker push $IMAGE_NAME
# 後続のステップでイメージ名を使えるように出力に設定
echo "IMAGE_NAME=$IMAGE_NAME" >> $GITHUB_ENV
# 6. データベースマイグレーション用ジョブを作成または更新
# gcloud run jobs deploy コマンドは、ジョブが存在しない場合は作成し、
# 存在する場合は更新するため、if文での分岐が不要になり、コードがシンプルになります。
- name: Deploy Migration Job
run: |
gcloud run jobs deploy ${{ env.GCP_SERVICE_NAME }}-migrate \
--region ${{ env.GCP_REGION }} \
--image ${{ env.IMAGE_NAME }} \
--set-cloudsql-instances ${{ env.GCP_SQL_CONNECTION_NAME }} \
--command="php" \
--args="artisan,migrate,--force" \
--task-timeout=300s \
--set-env-vars="APP_KEY=${{ secrets.APP_KEY }},LOG_CHANNEL=stderr,DB_CONNECTION=mysql,DB_SOCKET=/cloudsql/${{ env.GCP_SQL_CONNECTION_NAME }},DB_DATABASE=${{ secrets.DB_DATABASE }},DB_USERNAME=${{ secrets.DB_USERNAME }},DB_PASSWORD=${{ secrets.DB_PASSWORD }}"
# 7. データベースマイグレーションジョブを実行
# execute コマンドがこのステップで実行されると仮定します。
# --no-wait フラグを追加することで、ジョブの完了を待たずに次のステップへ進みます。
# これにより、GitHub Actionsがハングアップするのを防ぎます。
# 注意: この場合、マイグレーションの成否をこのワークフローで確認することはできません。
- name: Execute Migration Job (Asynchronously)
run: |
gcloud run jobs execute ${{ env.GCP_SERVICE_NAME }}-migrate --region ${{ env.GCP_REGION }} --no-wait
# 8. Cloud Runへデプロイ
- name: Deploy to Cloud Run
run: |
gcloud run deploy ${{ env.GCP_SERVICE_NAME }} \
--image ${{ env.IMAGE_NAME }} \
--region ${{ env.GCP_REGION }} \
--platform managed \
--quiet \
--add-cloudsql-instances ${{ env.GCP_SQL_CONNECTION_NAME }}
# 必要に応じて他の環境変数を設定
# --set-env-vars="APP_NAME=Laravel,APP_ENV=production"
GCP上のJOB作成
CI/CDを動かす前に、一度だけGCPコンソール上でダミーのジョブを作成しておく方法です。一度作ってしまえば、2回目以降のワークフロー実行では update コマンドが成功するようになります。
-
GCPコンソールに移動:
- 1 のページを開きます。
- 上部にある [JOBS] タブをクリックします。
-
ジョブの作成:
- [CREATE JOB] をクリックします。
-
コンテナイメージのURL:
us-docker.pkg.dev/cloudrun/container/helloのような、何でも良いので公開されているダミーのイメージURLを入力します。後でCI/CDが正しいイメージに更新してくれるので、中身は問いません。 -
ジョブ名:
livewire2-migrateと、ワークフローで指定している名前と完全に一致させます。 -
リージョン:
asia-northeast1を選択します。 - [作成] をクリックします。