トラス構造が幾何学的に組まれた建築物のファサード
技術解説

Laravelスターターキットを本番投入する前にSREが見るべき3つの落とし穴

目次を見る

Laravel(PHPで書かれたWebアプリケーションフレームワーク)製のスターターキットを使って、顧客サポートポータルのようなアプリケーションを素早く立ち上げたいチームに向けた内容です。開発速度を優先するスターターキットが、本番運用時にどんな落とし穴を生みやすいかを整理しました。

同じような要件のアプリケーションを毎回ゼロから作るのは非効率です。認証、チケット管理、権限制御、ダッシュボードといった機能は、案件が変わってもほぼ共通しています。そこで「NEXORA」のような、Laravel 13・PHP 8.3・MariaDB 10.11・DDEV(Dockerベースの再現可能な開発環境ツール)を組み合わせたスターターキットが登場しています。ただし、こうしたキットをそのまま本番環境に持ち込む際には、SRE(Site Reliability Engineering、信頼性を保ちながらシステムを運用する職能)の視点で見落としやすい点がいくつかあります。

何が起きるか:ローカル最適化が本番の可用性を脅かす

スターターキットは「開発者がその日のうちにログイン画面を見られること」を目標に設計されています。

DDEVによるコンテナ化や、composer.lock(PHPの依存パッケージのバージョンを固定するファイル)によるロックは、ローカル環境の再現性を高めるための仕組みです。

しかし、この再現性は「開発者のPC上で同じ動きをすること」を保証するだけで、本番環境での可用性やスケーラビリティを保証するものではありません。

典型的に起きるのは次のような事象です。単一のMariaDBインスタンスが前提になっていて冗長化構成がない、権限チェックのテストはあってもSLO(サービスレベル目標、障害時にどこまでの性能低下を許容するかの基準)が定義されていない、ログや指標の出力が開発時のデバッグ用途にとどまっている、といった状態です。障害範囲は「ポータルが見えなくなる」程度にとどまらず、権限制御のロジックがアプリケーション層だけに依存している場合、DBの接続不調時に意図しないアクセス許可が発生するケースもあり得ます。

なぜ起きるか:設計思想の違いを段階的に分解する

原因を一段ずつ分解してみます。

第一に、スターターキットの設計目標が「再利用性」と「理解しやすさ」であり、「耐障害性」ではない点です。SPAやAPIレイヤーをあえて持たない構成は学習コストを下げますが、裏を返せばフロントエンドとバックエンドが密結合になり、片方の障害がもう片方に波及しやすい構造でもあります。

第二に、権限制御のテストと、運用時の信頼性テストは別物という点です。NEXORAの権限制御は、Laravelのポリシー(アクセス可否を判定するクラス)とミドルウェア、ユーザースコープ付きクエリで構成されています。たとえば以下のようなポリシーメソッドです。

public function view(User $user, Ticket $ticket): bool
{
    return $user->isStaff() || $ticket->user_id === $user->id;
}

このコードは「他人のチケットURLを直接叩いても拒否される」ことを保証します。実際、顧客AがブラウザでURLを書き換えて顧客Bのチケットにアクセスしようとしても拒否される、という自動テストが用意されています。ただし、このテストはあくまで機能テストです。DB接続がタイムアウトしたときにどう振る舞うか、キャッシュ層が落ちたときにセッションがどうなるかといった、障害注入を前提にしたテストではありません。

第三に、管理者ロックアウト対策がアプリケーションレベルの安全装置にとどまっている点です。NEXORAには「最後のSuper Adminを降格・無効化できないようにする」仕組みがあります。これは業務ロジックのミスを防ぐには有効ですが、インフラ障害によって管理画面自体に誰もログインできなくなる事態への備えにはなりません。

自分のプロジェクトが該当するかの確認方法

導入を検討しているスターターキットが本番運用に耐えるかどうか、次の観点で確認してみてください。

# docker-compose.yml や .ddev/config.yaml を確認し
# データベースサービスが単一コンテナ構成かどうかを見る
cat .ddev/config.yaml | grep -i database

# composer.json でLaravelとPHPのバージョンを確認
cat composer.json | grep -E '"php"|"laravel/framework"'

# ログ出力先の設定を確認(stdout出力かファイル出力か)
cat config/logging.php | grep -A3 "'default'"

確認すべきポイントは次の3つです。

  • データベースの冗長化構成(レプリカ・フェイルオーバー)がテンプレートに含まれているか
  • ログがファイルではなくstdout(標準出力)に出せるか。コンテナ運用でログ収集基盤に流す前提か
  • SLO・アラート閾値に関する記述がREADMEやドキュメントに存在するか(存在しないことがほとんどです)

これらがキットに含まれていない場合、それは欠陥ではなく「スコープ外」というだけです。問題は、導入する側がそれを自覚せずに本番投入してしまうことです。

対策の手順

スターターキットを土台にしつつ、SREの観点で最低限補強すべき手順を示します。

1. IaC化してインフラを宣言的に管理する

DDEVの設定をそのまま本番に持ち込むのではなく、Terraform(宣言的にクラウドリソースを定義するIaCツール)やPulumi(プログラミング言語でIaCを書けるツール)でDB・ロードバランサー・コンテナオーケストレーションを定義し直します。これにより、環境差異による障害の再現性と復旧の速さが変わってきます。

2. SLOを最初に決めてからアラートを設計する

「チケット作成APIの成功率99.5%以上」「ログイン応答時間p95で500ms以内」のように、まず利用者視点の指標を決めます。SLOが先、アラート設計は後です。順番を逆にすると、意味のない閾値ベースのアラートが量産されます。

3. オブザーバビリティを機能テストと切り離して追加する

権限制御の自動テストとは別に、Prometheus(メトリクス収集ツール)やOpenTelemetry(分散トレーシングの標準規格)を使い、DB接続エラー率やキューの滞留状況を可視化します。Laravelであればlaravel/telescopeやsentry/sentry-laravelのようなパッケージで最低限の計装を入れられます。

4. 障害対応をPlaybook化する

「最後のSuper Adminがロックアウトされた場合の復旧手順」のような、アプリケーション固有の落とし穴は運用Playbookに明文化しておきます。コード上の安全装置に加えて、人間が読む手順書があることで、障害対応の属人化を防げます。

スターターキットは「権限ロジックの再利用」には強いが、「可用性・SLO・障害対応」はほぼ含まれないため、導入側が別途設計する前提で扱う必要があります。

まとめ

Laravelのスターターキットは、認証やチケット管理、権限制御といった反復作業を省略できる点で価値があります。

ただし、それは機能要件の再利用であって、可用性要件の再利用ではありません。

導入前には、DBの冗長化構成・ログ出力の形式・SLOの記述有無をチェックリスト化して確認し、足りない部分をTerraformやPulumiでのIaC化、SLOベースのアラート設計、オブザーバビリティの追加、障害対応Playbookの整備で埋めていくのが現実的な進め方です。

参考

I Got Tired of Rebuilding the Same Support Portal. So I Built One I Could Reuse.

この記事について: 本記事は AI を活用して作成し、forva AI 編集部が内容を確認・監修しています。

AI 駆動開発のご相談は forva AI へ。まずはお気軽にどうぞ。