1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Laravel12】Brefを使ってサーバーレスアプリケーションを作成する

Posted at

先日Laravel12が発表されたので、Laravelのスターターキットで作成したSPAをBrefを使ってAWS Lambdaにデプロイする流れをまとめてみます。

1. Brefとは

Brefは、AWS Lambda上でPHPアプリケーションを実行するためのオープンソースツールです。Lambdaはサーバーレス環境であり、従来のサーバー管理を不要にしますが、PHPはそのままではLambda上で動作しません。そこでBrefは、カスタムランタイムを提供し、LaravelのようなフルスタックフレームワークもLambda上で動かせるように工夫されています。

Brefを使用したLambdaのリクエスト ~ レスポンス生成までの流れ

image.png
引用:PHP-FPM runtime for AWS Lambda

1. クライアントからのHTTPリクエスト

ユーザーが アプリケーション にアクセスすると、そのリクエストは Amazon API Gateway へ送られます。

2. API Gatewayによるルーティング

API Gatewayは、設定されたエンドポイント(URLパスやメソッドなど)に基づいて、AWS Lambda 関数(Brefを用いたPHPランタイム)を呼び出します。

3. Lambdaの起動とBrefの処理

Lambda関数が呼び出されると、event(API Gatewayから渡されるリクエストデータ)とcontext(Lambdaの実行コンテキスト情報)がLambdaランタイムに渡されます。
Bref はカスタムランタイムとして、Lambdaのライフサイクルに合わせて起動します。具体的には、bootstrap と呼ばれるバイナリがイベントを受け取り、FastCGI プロトコルを通じて PHP-FPM に処理を委ねます。

4. PHP-FPMでのリクエスト処理

PHP-FPMがFastCGIリクエストを受け取り、index.php(Laravelの場合は public/index.php)をエントリーポイントとしてアプリケーションを実行します。
ここでLaravelやその他のWebフレームワークの処理が行われ、最終的にレスポンスが生成されます。

5. レスポンスの返却

PHP-FPMが生成したレスポンスをFastCGIレスポンスとしてBref に返却します。
BrefはそのレスポンスをLambdaのフォーマット(JSON形式など)に変換し、LambdaがAPI Gatewayに応答します。
API GatewayはレスポンスをHTTPレスポンスに変換し、クライアントへ返却します。

なぜBrefを使うのか

  • コスト削減: まずなんと言っても安いです。EC2やホスティングサービスを使うよりも圧倒的にコストを削減できます。
  • スケーラビリティ: 自動でスケールアウト・スケールインするため、アクセス増加時にも柔軟に対応可能です。
  • 運用の簡素化: サーバー管理の負荷が大幅に軽減され、開発に専念できます。

2. 開発環境の構築

必要なツール・前提条件

  • PHP 8.3
  • Laravel 12
  • AWS CLI
  • Serverless Framework v3
  • Bref

AWS CLIのインストール

AWS CLIをインストールし、以下のコマンドで認証情報を設定します。

aws configure

Serverless Frameworkのインストール

npmを利用してServerless Frameworkをグローバルにインストールします。
※Serverless Frameworkはv4まで出ていますが、動作が非常に不安定ということでBref公式から非推奨とされています。そのため、今回はv3を使用します。

npm install -g serverless@3

Laravelプロジェクトの作成

今回はLaravel12のスターターキットを利用してプロジェクトを作成します。

  • まず、Composer経由でLaravelインストーラをインストールします。
composer global require laravel/installer
  • 次に、LaravelインストーラCLIを使用して、新しいLaravelアプリケーションを作成します。
laravel new my-app

この時、使用するフロントエンドの種類を聞かれますが、今回はReactを選択します。

  • 後はJSパッケージをインストール&ビルドして、開発環境を立ち上げれば完了です。
cd my-app
npm install && npm run build
composer run dev

Brefのセットアップ

LaravelプロジェクトにBrefを導入し、インフラストラクチャの設定を行います。

Laravelプロジェクトのルートディレクトリで、Composerを使ってBrefをインストールします。

composer require bref/bref

次に、プロジェクトのルートディレクトリにserverless.ymlファイルを作成し、Lambda用の設定を記述します。

service: laravel-react

provider:
    name: aws
    region: ap-northeast-1 # 東京リージョンを指定

package:
    patterns:
        - '!node_modules/**'
        - '!public/storage'
        - '!storage/**'
        - '!tests/**'
        - '!database/*.sqlite'

functions:

    web:
        handler: public/index.php
        runtime: php-83-fpm
        timeout: 28 
        events:
            - httpApi:
                path: /{proxy+} 
                method: ANY
    artisan:
        handler: artisan
        runtime: php-83-console
        timeout: 720

plugins:
  - ./vendor/bref/bref
  - serverless-lift

constructs:
    website:
        type: server-side-website
        assets:
            '/build/assets/*': public/build/assets/
            '/favicon.ico': public/favicon.ico
            '/robots.txt': public/robots.txt
各セグメントの解説
  • service
service: laravel-react

Serverless Frameworkにおけるプロジェクト名を定義します。ここでは「laravel-react」という名前のサービスとしてデプロイされます。この名前はCloudFormationスタックやS3バケットのプレフィックスなどにも使われます。

  • provider
provider:
    name: aws
    region: ap-northeast-1 # 東京リージョンを指定

デプロイ先のクラウドプロバイダーとリージョンを指定します。awsを使い、東京リージョン(ap-northeast-1)で各リソースが作成されます。

  • package
package:
    patterns:
        - '!node_modules/**'
        - '!public/storage'
        - '!storage/**'
        - '!tests/**'
        - '!database/*.sqlite'

デプロイに含めないファイルやフォルダを定義しています。不要なファイルを除外することで、デプロイパッケージのサイズを削減します。

node_modules/**:Laravelでは不要

public/storage:アップロードファイル(S3などで管理する想定)

storage/**:ログやキャッシュなど実行時のみ必要なもの

tests/**:テストコード

database/*.sqlite:ローカル環境で使うSQLiteファイル

  • functions
functions:

    web:
        handler: public/index.php
        runtime: php-83-fpm
        timeout: 28 
        events:
            - httpApi:
                path: /{proxy+} 
                method: ANY

web関数は、HTTPリクエストを処理するLaravelのメインエントリポイントです。

handler: public/index.php をLambdaのエントリポイントに指定

runtime: php-83-fpm(BrefによるPHP 8.3 + FPM環境)

timeout: 最大28秒

events: HTTP API Gatewayで全パス・全メソッドに対応

    artisan:
        handler: artisan
        runtime: php-83-console
        timeout: 720

artisan関数は、LaravelのCLIコマンド(バッチ処理やマイグレーションなど)用です。

handler: artisan コマンドをエントリポイントに

runtime: php-83-console(CLI用のBrefランタイム)

timeout: 長時間処理に備えて最大値の720秒を指定

  • plugins
plugins:
  - ./vendor/bref/bref
  - serverless-lift

使用するServerless Frameworkのプラグインを指定します。

bref: PHP用のLambdaランタイムを提供

serverless-lift: サーバーサイドWebアプリや静的ファイル配信のための簡潔な構成を可能にするプラグイン

  • constructs
constructs:
    website:
        type: server-side-website
        assets:
            '/build/assets/*': public/build/assets/
            '/favicon.ico': public/favicon.ico
            '/robots.txt': public/robots.txt

serverless-liftを使った、S3 + CloudFront構成での静的アセットの配信設定です。

  • type: server-side-website:サーバーサイドアプリ(Laravelなど)に最適化された構成

  • assets: 指定したファイル群をS3にアップロードしてCDN経由で配信

3. アプリケーションのデプロイ

最後に、ローカルでの動作確認から、AWS Lambdaへのデプロイ、そしてデプロイ後の動作確認までの手順を見ていきます。

ローカルでの動作確認

まず、開発環境でLaravelアプリケーションが正しく動作するかを確認します。

 composer run dev

ブラウザで http://localhost:8000 にアクセスし、初期画面が表示されるかチェックしてください。

デプロイ

Serverless Frameworkを用いてデプロイします。プロジェクトルートで以下のコマンドを実行してください。

serverless deploy

デプロイが成功すると、出力にAPIエンドポイントのURLが表示されます。

デプロイ後の動作確認

デプロイ後に表示されたAPIエンドポイントにアクセスし、アプリケーションが正しく動作するか確認します。

image.png
無事アクセスできました!

終わりに

AWSのコンソールをほぼ一切触らずに、CLIからサーバーレスアプリケーションがコマンドを数回打つだけで完成できました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?