Amazon Web Services ブログ
サーバーレス LAMP スタック – Part 4: サーバーレス Laravel アプリの構築
本投稿は AWS サーバーレス アプリケーションのシニアデベロッパーアドボケートである Benjamin Smith による寄稿です。
本シリーズの他のパートは以下のリンクからアクセスできます。また、関連するサンプルコードはこちらの GitHub リポジトリにあります。
- パート1:サーバーレス LAMP スタックの紹介
- パート2:リレーショナルデータベース
- パート3:Webサーバーの置き換え
- パート5:CDK コンストラクトライブラリ
- パート6:MVC からサーバーレスマイクロサービスへ
この投稿では、サーバーレスアプローチで Laravel アプリケーションをデプロイする方法を学びます。
これは「サーバーレス LAMP スタック」シリーズの4番目の投稿になります。過去の投稿はこちらです。
- パート1:サーバーレス LAMP スタックの紹介
- パート2:リレーショナルデータベース
- パート3:Webサーバーの置き換え
Laravel は PHP 用のオープンソースの Web アプリケーションフレームワークです。フレームワークを使用すると、開発者は一般的なコンポーネントとモジュールを再利用することで、より速く構築できます。また、開発標準に準拠することにより、長期的なメンテナンスにも役立ちます。ただし、従来の LAMP スタックを使用して PHP フレームワークをスケーリングする場合は、まだ課題があります。サーバーレスアプローチを使用してフレームワークをデプロイすると、これらの課題の解決に役立ちます。
Laravel アプリケーションのサーバーレスインフラストラクチャへの展開を簡素化する方法は数多くあります。ここで紹介する方法では、AWSサーバーレスアプリケーションモデル(AWS SAM)テンプレートを使用しています。これによって、Laravel アプリケーションが単一の Lambda 関数にデプロイされます。この関数は、Bref FPM カスタムランタイムレイヤーを使用して PHP を実行します。AWS SAMテンプレートは、「サーバーレス LAMP スタック – パート3: Webサーバーの置き換え」で詳細に説明されている次のアーキテクチャをデプロイします。
AWS SAM を使用した Laravel と Bref のデプロイ
Composer は、PHP の依存関係管理ツールです。プロジェクトライブラリと、Laravel や Bref などの依存関係を宣言して管理できます。
次の手順を使用して、AWS SAM で Laravel と Bref をデプロイします:
- Composer を使用してLaravel インストーラをダウンロードします。
composer global require Laravel/installer
- Laravel をインストールします。
composer create-project --prefer-dist laravel/laravel blog
- Laravel プロジェクトで、Composer を使用して Bref をインストールします。
composer require bref/laravel-bridge
- アプリケーションのルートディレクトリで AWS SAMテンプレートのクローンを作成します。
git clone https://github.com/aws-samples/php-examples-for-aws-lambda/
- ディレクトリを「0.4-Building-A-Serverless-Laravel-App-With-AWS-SAM」に変更します。
cd 0.4-Building-A-Serverless-Laravel-App-With-AWS-SAM
- AWS SAM CLI のガイド付きデプロイを使用してアプリケーションをデプロイします。
sam deploy -g
AWS SAM がアプリケーションをデプロイすると、Amazon CloudFront ディストリビューションのドメイン名が返されます。このディストリビューションからサーバーレス Laravel アプリケーションへアクセスできます。
Lambda 向けの Laravel の設定
Laravel を Lambda 関数で実行するには、いくつかの構成変更が必要です。
セッションデータストア
Lambda インスタンスには 512 MB の一時ディレクトリ(ファイルシステム)が含まれていますが、これは耐久性のあるストレージ向けではない一時的なリソースです。これは、関数呼び出しごとに同じ Lambda インスタンスが再利用される保証がないためです。
このため、Laravel セッションデータが必要な場合は、Lambda 関数の外部に保存する必要があります。サーバーレスアプリケーションで状態を管理するために利用できるさまざまなオプションがあります。この場合、セッションデータをデータベースに保存するか、ブラウザの Cookie を使用することをお勧めします。
Laravel の .env
ファイルを更新し、session_driver
に cookie を設定定します。
SESSION_DRIVER=cookie
ロギング
Laravel は、Monolog と呼ばれる PHP ロギングライブラリを実装しており、多くの宛先にログを書き込むことができます。Laravel Monolog は log channels
によってこれらの宛先を指定します。各チャネルは、 /config/logging.php
ファイル内で連想配列として定義されています。
Lambda インスタンスのファイルシステムは複数の Lambda 関数呼び出し間で共有されないため、アプリケーションログは Amazon CloudWatch Logs などの外部の中央の場所に書き込むことが望ましいです。PHP によって発行されるすべてのエラー、警告、および通知は、CloudWatch Logs に転送されます。これにより、単一の場所から将来の分析のためにログを簡単に表示、検索、フィルタリング、またはアーカイブできます。これを設定するには、Laravel .env
ファイルに以下を追加します。
LOG_CHANNEL=stderr
これにより、stderr
チャネルがすべてのアプリケーションログを書き込むために使用されることが保証され、それは CloudWatch Logs に自動的に転送されます。このチャネルは /config/logging.php
で定義されています:
'stderr' =>
[
'driver' => 'monolog',
'handler' => StreamHandler::class,
'formatter' => env('LOG_STDERR_FORMATTER'),
'with' => [
'stream' => 'php://stderr',
],
],
コンパイルされたビュー
ビューには、アプリケーションによって提供されるHTMLが含まれ、アプリケーションロジックとプレゼンテーションロジックが分離されます。デフォルトでは、ビューはアプリケーションの storage
ディレクトリ内でオンデマンドでコンパイルされます。
Lambda にはストレージディレクトリへの書き込みアクセス権がないため、関数が /tmp
ディレクトリにビューを書き込むように Laravel を設定する必要があります。これは、各 HTTP リクエストの期間中にのみ必要な一時データ用の一時ファイルシステムです。
.env
ファイルに次の行を追加して、コンパイルされたビューのために新しいディレクトリパスを使用するように Laravel を設定します。
VIEW_COMPILED_PATH=/tmp/storage/framework/views
Laravel はアプリケーションへのコンポーネントの登録または「ブートストラップ」のためにに service providers
を使用します。AppServiceProvider.php
ファイルは、すべてのビューで共有されるデータのための中心的な場所です。次のコードを Providers/AppServiceProvider.php
ファイルに追加します。
public function boot() {
// Make sure the directory for compiled views exist
if (! is_dir(config('view.compiled'))) {
mkdir(config('view.compiled'), 0755, true);
}
}
これにより、ビューディレクトリが存在しない場合は、Lambda 関数の呼び出しごとにビューディレクトリが自動的に作成されます。
Amazon S3 によるファイルシステムの抽象化
Laravel は Flysystem と呼ばれる ファイルシステム抽象化 パッケージを使用しています。これにより、ファイルシステムの場所を構成するための単純なドライバーメカニズムが提供されます。Lambdaの /tmp ディレクトリは一時的なものであるため、ファイルシステムの場所は Lambda 関数の外部にある必要があります。次の行を .env
ファイルに追加して、Amazon S3 ファイルシステムドライバーを使用するように Laravel を設定します。
FILESYSTEM_DRIVER=s3
AWS SAM テンプレートによって、これらのオブジェクトを保存するための S3 バケットをデプロイできます。
Storage:
Type: AWS::S3::Bucket
Properties:
BucketName: php-example-laravel-FileSystemBucket
バケット名は、AWS SAM テンプレート内から環境変数として Lambda 関数に提供されます。
Environment:
Variables:
AWS_BUCKET: !Ref Storage
Lambda 関数には、IAM ポリシー定義を使用して、S3 バケットへの読み取り/書き込み権限が付与されます。
Policies:
- S3FullAccessPolicy:
BucketName: !Ref Storage
Laravel のファイルシステム構成は config/filesystems.php
で指定します。ここで AWS SAM 環境変数を使用して S3 ファイルシステムディスクを定義します。
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'token' => env('AWS_SESSION_TOKEN'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
],
AWS アカウント情報とバケット ARN は、Laravel の env() 関数を使用して、PHP を実行している Lambda 環境から取得できます。
パブリックなアセットファイル
Laravel には、画像や CSS ファイルなどのように、パブリックにアクセス可能なファイルを格納するためのパブリックディスクドライバーがあります。デフォルトでは、パブリックディスクドライバーはこれらのファイルを storage/app/public/
に保存するよう構成されています。これらのファイルは S3 に保存する必要があります。このため、config/filesystems.php
の構成を次のように変更します。
'public' => env('FILESYSTEM_DRIVER_PUBLIC', 'public_local'),
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public_local' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'token' => env('AWS_SESSION_TOKEN'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
],
's3_public' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'token' => env('AWS_SESSION_TOKEN'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_PUBLIC_BUCKET'),
'url' => env('AWS_URL'),
],
],
これにより、S3ドライバーを使用する s3_public という名前の新しいファイルシステムディスクが追加されます。Laravel のenv() 関数が環境変数 env( ‘AWS_PUBLIC_BUCKET’ ) を取得して、バケットの場所を設定/構成します。バケット名は環境変数として Lambda 関数に渡されます。
次の行を env ファイルに追加して S3 を使用するようにパブリックディスクを構成します:
FILESYSTEM_DRIVER_PUBLIC=s3
ビューテンプレートでの静的アセットの参照
Laravel の asset()
ヘルパー関数では、リクエストの現在の URL スキーム(HTTPまたはHTTPS)を使用してアセットの URL を生成できます。
$url = asset('img/photo.jpg');
これらのアセット自体は S3 に保存されることで CloudFront のグローバル CDN を介して提供可能になります。.env ファイルで ASSET_URL 変数を設定して、URL ホストを構成します。
これにより、アプリケーションは CloudFront ドメインを介して S3 のアセットを正しく参照できます。Laravel のネイティブ asset() ヘルパー関数は、次の形式でビューテンプレート内から使用されます。
<img src="{{ asset('assets/icons.png') }}">
補足: サーバーレス Laravel アプリケーションのデプロイ
- Bref、PHP 用のオープンソースのカスタムランタイム。最近 新たなプルリクエストをマージし、Lambda 向けに自動で Laravelを構成できるようになりました。この新しいパッケージでは、Amazon SQS を Laravel キュージョブシステムと統合する方法も提供しています。
- Laravel Vapor : Laravel のサーバーレスデプロイプラットフォームです。これは、AWSクラウド上で Laravel チームによって構築された有料サービスです。
まとめ
この投稿では、AWS SAM やサーバーレスアプローチを使用して PHP Laravel アプリケーションをデプロイする方法について説明しました。S3 で外部ファイルシステムと静的アセットを使用してセッションストアと集中ロギングを実装するために必要な初期 Laravel 構成手順について説明しました。
PHP開発チームは、ビルド方法を変更することなく、コードの配布に集中できます。さあ、PHP を使用してサーバーレスアプリケーションの構築を開始しましょう。
付随するコードと手順については、この GitHubリポジトリにアクセスしてください。
原文はこちらです。