Laravel + Nginx アプリケーションを GCP にデプロイする
目的
GCP (Google Cloud Platform) 上での Laravel アプリケーションのデプロイに関する情報はまだ少ないため、私自身の経験と構築手順を共有することを目的としています。特に Nginx を利用したデプロイ方法に焦点を当て、同じ課題を持つ開発者の一助となれば幸いです。
やったこと
1.GCP ネットワークの構築
Cloud Run と Cloud SQL が連携するためのネットワーク基盤を構築しました。
- デフォルト VPC ネットワークの利用: GCP プロジェクトで提供されるデフォルトの VPC ネットワークを活用。
- プライベート IP 接続の確立:
セキュリティとベストプラクティスのため、Cloud Run と Cloud SQL 間はプライベート IP 接続が必須。パブリック IP はファイアウォールで制限されます。
Cloud SQL 接続: VPC と Cloud SQL 間でPrivate Service Connectionを設定し、プライベート IP でアクセス可能にしました。 - Cloud Run からのアクセス: Cloud Run が VPC 内の Cloud SQL にアクセスできるよう、Serverless VPC Access コネクタを作成し、Cloud Run サービスに割り当てました。
これにより、Laravel + Nginx アプリケーションが Cloud SQL と安全に連携できるネットワーク環境が整いました。
2. Cloud Build を用いたコンテナイメージのビルドとプッシュ
Cloud Build を活用し、コンテナイメージのビルドと Artifact Registry へのプッシュを行いました。今回は、PHP と Nginx を一つのコンテナに統合しています。
Cloud Build の設定ファイル (cloudbuild.yaml)
プロジェクトルートに以下の cloudbuild.yaml を配置し、Docker イメージのビルドと Artifact Registry へのプッシュのステップを定義しました。
# cloudbuild.yaml
steps:
- name: 'gcr.io/cloud-builders/docker'
args: [
'build', '--no-cache',
'-t', 'YOUR_REGION-docker.pkg.dev/${PROJECT_ID}/YOUR_REPOSITORY_NAME/YOUR_IMAGE_NAME:latest',
'-f', 'Dockerfile.unified', '.'
]
- name: 'gcr.io/cloud-builders/docker'
args: [
'push', 'YOUR_REGION-docker.pkg.dev/${PROJECT_ID}/YOUR_REPOSITORY_NAME/YOUR_IMAGE_NAME:latest'
]
images:
- 'YOUR_REGION-docker.pkg.dev/${PROJECT_ID}/YOUR_REPOSITORY_NAME/YOUR_IMAGE_NAME:latest'
YOUR_REGION, YOUR_REPOSITORY_NAME, YOUR_IMAGE_NAME は、ご自身の環境に合わせて置き換えてください。
ビルドの実行と Artifact Registry へのプッシュ
gcloud builds submit --config cloudbuild.yaml . コマンドでイメージをビルドし、Artifact Registry へプッシュしました。
3. 統合コンテナの Dockerfile (Dockerfile.unified)
PHP-FPM と Nginx を単一のコンテナで動作させるための Dockerfile.unified を作成しました。
# Dockerfile.unified
FROM php:8.1-fpm-buster
ENV COMPOSER_ALLOW_SUPERUSER=1 \
COMPOSER_HOME=/composer
RUN apt-get update && \
apt-get -y install --no-install-recommends \
git unzip libzip-dev libicu-dev libonig-dev \
nginx supervisor && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
docker-php-ext-install intl pdo_mysql zip bcmath
COPY --from=composer:2.2 /usr/bin/composer /usr/bin/composer
COPY ./infra/nginx/default.conf /etc/nginx/conf.d/default.conf
COPY ./infra/php/php.ini /usr/local/etc/php/php.ini
COPY ./infra/php/zz-fpm.conf /usr/local/etc/php-fpm.d/zz-fpm.conf
COPY ./infra/supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
WORKDIR /data
COPY ./src /data
RUN composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
RUN rm -f /etc/nginx/sites-enabled/default
RUN ln -s /etc/nginx/conf.d/default.conf /etc/nginx/sites-enabled/default
RUN mkdir -p /var/log/nginx && chown -R www-data:www-data /var/log/nginx
RUN chown -R www-data:www-data /data/storage /data/bootstrap/cache
RUN chmod -R 775 /data/storage /data/bootstrap/cache
EXPOSE 80
CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
4. Nginx 設定ファイル (infra/nginx/default.conf)
アプリケーションへのリクエストを処理し、PHP-FPM にルーティングするための Nginx 設定です。
# infra/nginx/default.conf
server {
listen 80;
root /data/public;
index index.php;
charset utf-8;
location / { try_files $uri $uri/ /index.php?$query_string; }
location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; include fastcgi_params; }
# その他のセキュリティヘッダーやログ設定
}
Nginx 設定のポイント:
- listen 80;: コンテナ内の Nginx がポート 80 でリクエストを受け付けます。
- root /data/public;: Laravel の public ディレクトリを Web ルートに設定。
- fastcgi_pass 127.0.0.1:9000;: 同じコンテナ内の PHP-FPM にリクエストを転送します。
5. PHP 設定ファイル (infra/php/php.ini)
PHP の基本的な動作設定を定義します。
; infra/php/php.ini
upload_max_filesize = 128M
post_max_size = 128M
memory_limit = 256M
date.timezone = Asia/Tokyo
display_errors = On
6. Supervisor 設定ファイル (infra/supervisor/supervisord.conf)
Supervisor は、単一コンテナ内で Nginx と PHP-FPM の両プロセスを管理し、コンテナ起動時に両サービスが適切に起動・維持されるようにします。
; infra/supervisor/supervisord.conf
[supervisord]
nodaemon=true
[program:php-fpm]
command=/usr/local/sbin/php-fpm --nodaemonize --allow-to-run-as-root
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stderr_logfile=/dev/stderr
[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stderr_logfile=/dev/stderr
Supervisor 設定のポイント:
- nodaemon=true: Supervisor 自体をフォアグラウンドで実行し、Docker コンテナのメインプロセスとして機能させます。
- [program:php-fpm] と [program:nginx]: それぞれのサービスを定義し、自動起動と再起動を設定。
- stdout_logfile / stderr_logfile: 各プロセスのログをコンテナログとして出力されるよう設定。
7. Cloud SQL のセットアップと Cloud Run へのデプロイ
コンテナイメージ準備後、Cloud SQL をセットアップし、コンテナイメージを Cloud Run にデプロイして連携させました。これらの設定は主に **GCP コンソール(GUI)**を通じて行いました。
Cloud SQL (MySQL) インスタンスの作成と設定
Laravelのデータストアとして Cloud SQL for MySQL を利用しました。
- インスタンス作成: GCP コンソールで新規 MySQL インスタンスを作成し、プライベート IP アドレスを有効にしました。
- プライベート IP 設定: VPC ネットワークにプライベートサービス接続を設定。
- データベースとユーザー作成: アプリケーション用のデータベースとユーザーを作成し、権限を付与。
Cloud Run へのデプロイと Cloud SQL との連携
ビルドした統合コンテナイメージを Cloud Run にデプロイし、Cloud SQL との接続を設定しました。
- Cloud Run サービス作成: GCP コンソールで新規サービスを作成し、Artifact Registry のコンテナイメージを指定。
- VPC Connector の設定: Cloud Run と Cloud SQL をプライベート IP で接続するため、Serverless VPC
- Cloud Run サービスの編集にてアウトバウンド トラフィック用の VPC に接続するチェックをつけてdefaultのVPCにネットワークを割り当てました。
- 環境変数の設定: データベース接続に必要な環境変数 (DB_CONNECTION, DB_HOST など) を Cloud Run に設定。
- 自動スケーリングとリソース設定: 必要に応じてインスタンス数やリソース設定を調整。
これらの設定により、Cloud Run 上で Laravel + Nginx アプリケーションが起動し、プライベートネットワーク経由で Cloud SQL データベースと安全に通信できるようになりました。
Discussion