はじめに
PHPでAWS Lambdaを利用したアプリケーションを構築するには、カスタムランタイムが必要になります。BrefはLambdaでPHPを実行するためのランタイムとLaravel、SymfonyなどのPHPフレームワークとの統合を提供しています。

本記事では、このBrefを使ったLaravelアプリケーションの環境構築方法を解説していきます。
プロジェクトの概要
コンセプト
基本的にBrefはServerless Frameworkを介して利用しますが、今回はAWS CDKにBref用の専用Constructが用意されているので、CDKを利用することにしました。コードベースでのインフラ管理や拡張の容易性もCDKを選定した理由になります。
また、個人のテスト環境として比較的低コストで構築できるように最小構成で実装していきます。
成果物
完成品は以下に配置してあります。
システム構成
システム構成は以下の通りです。

Lambda関数が2つデプロイされているのは、API Gatewayに統合されているWebアプリケーションと php artisan migrate
などを実行するConsoleアプリケーションを分けているためです。EFSは後述しますが、データストレージの役割を担っています。
準備
Laravel
Laravel側の作業はBrefに必要なライブラリをインストールするだけです。
% composer require bref/bref bref/laravel-bridge --update-with-dependencies
CDK
CDK側では、BrefのConstructパッケージをインストールします。
% npm install @bref.sh/constructs
CDKの実装
CDK側の実装を見ていきます。
ネットワーク
EFSをマウントさせる都合上、VPC Lambdaである必要があります。コスト高になりがちなNAT Gatewayに関しては、今回はLambdaからインターネットに出ていく必要は無いので、作成をしない設定にしています。
const vpc = new ec2.Vpc(this, "BrefVpc", {
maxAzs: 1,
natGateways: 0,
restrictDefaultSecurityGroup: true,
subnetConfiguration: [
{
name: "BrefPrivate",
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
},
],
});
データストレージ
RDBのマネージドサービスは高価ですので、Laravelの初期状態で使えるSQLiteを選定し、EFSに database.sqlite
ファイルを配置するようにします。冗長化も不要なのでOneZoneを選択しています。
const fileSystem = new efs.FileSystem(this, "BrefEfs", {
vpc: vpc,
removalPolicy: cdk.RemovalPolicy.DESTROY,
performanceMode: efs.PerformanceMode.GENERAL_PURPOSE,
throughputMode: efs.ThroughputMode.BURSTING,
oneZone: true,
});
const accessPoint = this.fileSystem.addAccessPoint("BrefAccessPoint", {
path: "/bref"
createAcl: {
ownerUid: "1001",
ownerGid: "1001",
permissions: "750",
},
posixUser: {
uid: "1001",
gid: "1001",
},
});
アプリケーション
システム構成の項で紹介した通り、WebアプリケーションとConsoleアプリケーションの2つを用意しています。
Webアプリケーション
Webアプリケーションでは、Lambda関数とHTTPからのアクセス用にAPI Gatewayを統合します。Lambda関数は @bref.sh/constructs
に PhpFpmFunction
というBrefのレイヤーを追加したConstructがあるので、これを使用します。
const backendFn = new PhpFpmFunction(this, "BrefApiFunction", {
functionName: "ApiFunction",
handler: "public/index.php",
code: packagePhpCode("../laravel/", {
exclude: ["tests/**", "var/**"],
}),
timeout: cdk.Duration.seconds(28),
memorySize: 1024,
vpc: vpc,
filesystem: lambda.FileSystem.fromEfsAccessPoint(
accessPoint,
"/mnt/efs",
),
environment: {
APP_ENV: "production",
LOG_CHANNEL: "stderr",
DB_CONNECTION: "sqlite",
DB_DATABASE: "/mnt/efs/database.sqlite",
},
phpVersion: "8.4",
});
const api = new apigwv2.HttpApi(this, "BrefHttpApi", {
defaultIntegration: new integrations.HttpLambdaIntegration(
"Integration",
backendFn,
),
});
new cdk.CfnOutput(this, "ApiUrl", {
value: api.url!,
});
URLを CfnOutput
で出力するとデプロイ後のアクセスが楽になります。
Consoleアプリケーション
Brefには、ConsoleFunction
というConstructがあります。これは、artisanコマンドを実行するエンドポイントになります。
new ConsoleFunction(this, "BrefConsoleFunction", {
functionName: "ConsoleFunction",
handler: "artisan",
code: packagePhpCode("../laravel/", {
exclude: ["tests/**", "var/**"],
}),
timeout: cdk.Duration.seconds(28),
memorySize: 512,
vpc: vpc,
filesystem: lambda.FileSystem.fromEfsAccessPoint(
accessPoint,
"/mnt/efs",
),
environment: {
APP_ENV: "production",
LOG_CHANNEL: "stderr",
DB_CONNECTION: "sqlite",
DB_DATABASE: "/mnt/efs/database.sqlite",
},
phpVersion: "8.4",
});
artisanコマンドはaws cli経由で実行しますので、functionName
を定義しておくと後々便利です。
デプロイ・動作確認
デプロイして動作確認してみます。
% cdk deploy
(略)
Outputs:
BrefStack.ApiUrl = https://example.execute-api.ap-northeast-1.amazonaws.com/
出力されたURLにアクセスしてみます。
![Internal Server Error のタイトルで、Database file at path [/mnt/efs/database.sqlite] does not exist. のメッセージが出ている。](https://wptech.kiichiro.work/wp-content/uploads/2025/04/e6f5d404fcf83bb886fcbff5cd5339e9-1024x537.png)
当然、migrationが終わっていないのでエラーが表示されます。ConsoleFunctionを直接実行してmigrationします。aws cliを利用して以下を実行します。
% aws lambda invoke \
--function-name ConsoleFunction \
--region ap-northeast-1 \
--cli-binary-format raw-in-base64-out \
--payload '"migrate --force"' \
response.json
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST"
}
Lambdaの実行に問題がなければLaravelの画面が見られるようになるはずです。

まとめと感想
本記事では、BrefをCDKで利用してAWS Lambda上でLaravelを動かしてみました。また、低コストでの構築を目指し、最小構成の形を取りました。
BrefはLaravelアプリケーション側で意識することが少ないですので、かなり手軽にできるんじゃないかと思いました。デプロイパイプラインを整えれば、本番環境にも適用できると思います。