Laravel 13 で「認証基盤アプリのテンプレート」を整える:マルチドメイン・読み書き分離・Sanctum・Octane

概要

複数の案件で「管理画面 + フロント + API」の3層 Laravel アプリを繰り返し立ち上げていると、環境変数の設計や Docker まわりのボイラープレートで毎回消耗します。そこで、認証基盤を持つ Laravel アプリのテンプレートを1つ用意し、案件ごとに複製して使う運用に切り替えました。この記事では、そのテンプレートで固めた汎用的な部分を共有します。

対象とするのは次の要素です。

  • マルチドメイン(admin / front / api)を前提にした env 設計
  • MySQL の read/write ホスト分離
  • Sanctum による SPA 認証の前提設定
  • Octane・Redis・MinIO・Mailpit を含むローカル開発環境
  • Basic 認証・reCAPTCHA v3・Sentry などの「案件でだいたい要る」オプション

環境

  • PHP 8.3 系以上(Laravel 13 は 8.3〜8.5 に対応) / Laravel 13 系
  • MySQL 8.0 / Nginx
  • Redis(キャッシュ・セッション・キュー)
  • MinIO(S3 互換のローカルストレージ)
  • Mailpit(ローカルメール確認)
  • Node.js 24 系(LTS)

発生していた課題

案件を新しく始めるたびに、以下を毎回手で組んでいました。

  1. 管理画面・フロント・API でドメインを分ける構成
  2. .env に「どのキーが何のためにあるか」が分からないまま増えていく問題
  3. 本番で誤って有効化すると危険な設定(SQLログ等)の扱い
  4. ローカルでメール・ストレージ・キューをどう再現するか

とくに .env は、放っておくと「誰も意味を説明できないキーの山」になります。テンプレート側でキー名に意味を持たせ、コメントで役割を明示しておくのが最大の効きどころでした。

対応方法

1. env をカテゴリで区切って設計する

.env を、アプリ基本 / ドメイン / ログ / DB / セッション / 外部サービスといったブロックに分けて管理します。マルチドメイン前提のキーを最初から用意し、危険な設定には注意書きを添えます。

APP_NAME={サイト名}
APP_ENV={環境名}
APP_DEBUG={デバッグ表示設定}
APP_URL={サイトURL}

# --- マルチドメイン ---
ADMIN_DOMAIN={管理画面ドメイン}
FRONT_DOMAIN={フロントドメイン}
API_DOMAIN={APIドメイン}

# --- ログ(本番事故を防ぐための注意書きを添える)---
LOG_SQL_ENABLE=false        # 本番では必ず false
LOG_SQL_SLOW_QUERY_TIME={スロークエリ閾値}
LOG_LEVEL={ログレベル}

「本番で true にしてはいけない」キーは、コメントで明示しておくだけで事故率が下がります。

2. MySQL の read/write を分ける

負荷が上がってきたときにアプリ側を書き換えずに済むよう、テンプレート段階で読み書きホストを分離できるようにします。

DB_CONNECTION=mysql
DB_HOST={通常ホスト}
DB_HOST_READ={read用ホスト}
DB_HOST_WRITE={write用ホスト}
DB_DATABASE={DB名}

config/database.php 側では、read/write が未指定なら通常ホストにフォールバックする形にしておくと、ローカル(単一DB)と本番(分離)で同じコードが動きます。

'mysql' => [
    'read' => [
        'host' => [env('DB_HOST_READ', env('DB_HOST', '127.0.0.1'))],
    ],
    'write' => [
        'host' => [env('DB_HOST_WRITE', env('DB_HOST', '127.0.0.1'))],
    ],
    'sticky' => true, // 書き込み直後の読み取りを write に寄せる
    'driver' => 'mysql',
    'database' => env('DB_DATABASE'),
    // ...
],

sticky => true により、同一リクエスト内で書き込んだ直後の読み取りが write 側へ向き、レプリケーション遅延による「登録したのに一覧に出ない」を避けられます。

3. Sanctum で SPA 認証の前提を固める

フロントを SPA にするケースが多いので、Sanctum のステートフルドメインとセッション Cookie の設定をテンプレートに含めます。

SANCTUM_STATEFUL_DOMAINS={リクエスト元ドメイン}

SESSION_DOMAIN={Cookieドメイン属性}
SESSION_COOKIE={セッションID名}
SESSION_DRIVER=redis
SESSION_SECURE_COOKIE={本番はtrue}

Cookie ベースの SPA 認証では、SANCTUM_STATEFUL_DOMAINSSESSION_DOMAIN の噛み合わせでハマりがちです。テンプレート段階で「フロントとAPIが同一の親ドメイン配下に来る」前提を明記しておくと、案件ごとの調整が最小限で済みます。

4. ローカルは Docker + make で一発

ローカル環境は Docker で組み、make に主要操作を集約します。

# 初回
make start-project
make fresh          # 失敗したらリトライ

# 2回目以降
make up             # 起動
make down           # 停止
make destroy        # データ削除(再起動時は make rebuild)

ストレージは MinIO、メールは Mailpit で受けるため、S3 と SES を本物に繋がなくてもファイルアップロードとメール送信を確認できます。

# ローカルは MinIO(S3互換)
FILESYSTEM_DISK=s3
AWS_ENDPOINT={MinIOエンドポイント}
AWS_USE_PATH_STYLE_ENDPOINT=true

# ローカルは Mailpit
MAIL_MAILER=smtp
MAIL_HOST={Mailpitホスト}
MAIL_PORT={Mailpitポート}

本番では FILESYSTEM_DISK を実 S3 に、MAIL_MAILER を SES に差し替えるだけで、アプリコードは変えません。

5. 「だいたい要る」オプションを空枠で用意

案件で高確率で必要になるものは、値は空でもキーだけ置いておきます。

FRONT_BASIC_AUTH={有無}
ADMIN_BASIC_AUTH={有無}
RECAPTCHAV3_SITEKEY=
RECAPTCHAV3_SECRET=
SENTRY_LARAVEL_DSN=
OCTANE_SERVER={サーバ種類}
OCTANE_MAX_EXECUTION_TIME={最大実行時間}

「後から入れる」より「枠だけあって空」のほうが、導入時の心理的コストが圧倒的に低いです。

確認方法

  • make fresh 後、admin / front / api それぞれのドメインでルーティングが解決されること
  • Mailpit の受信画面にメールが届くこと
  • MinIO のバケットにアップロードしたファイルが入ること
  • read/write を分けた設定でも、書き込み直後の読み取りが正しく取れること(sticky 確認)

注意点

  • LOG_SQL_ENABLE を本番で true にしない
  • Octane 導入時は、シングルトンやスタティックプロパティにリクエスト間で状態が残らないか要確認
  • Sanctum の Cookie 認証はドメイン設計に強く依存するため、案件開始時に「フロントとAPIのドメイン関係」を先に決める

まとめ

認証基盤アプリを毎回ゼロから作らず、マルチドメイン・read/write 分離・Sanctum・ローカル一発起動を含んだテンプレートに寄せることで、立ち上げの初速が大きく変わりました。とくに .env を「意味の分かるキー + 危険設定の注意書き」で設計しておくのは、コスト対効果が非常に高い工夫です。案件ごとの差分だけに集中できる状態を作ることが、この取り組みの狙いです。

\ 最新情報をチェック /

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください