はじめに
Laravelで開発を始めようとしたとき、最初の壁になるのが開発環境づくりですよね。
PHPのバージョン、MySQLのインストール、メールの送信テスト……。
1つずつ自分のパソコンに入れていくと、それだけで1日が終わってしまいます。
この連載では、ポートフォリオとして作っている社内業務システム「office-hub」の開発工程を、フェーズごとに記録しています。
前回の#0 題材選びと設計書づくりで設計が終わったので、今回の#1からいよいよ手を動かします。
この記事では、Laravel Sailを使って、
- Laravel+MySQL+メール確認ツールの環境をまとめて作る
- 最初の起動の前に
.envを設定する(ここが大事です) - React の画面からログインできるように、APIと認証の下準備をする
までを、実際につまずいたところも含めて紹介します。
コマンドは自分でターミナルに打っていますが、設定の意味や手順はAI(Claude)に相談しながら進めました。
Laravel Sailとは?
Laravel Sail は、Laravel公式のDocker開発環境です。
Dockerは、パソコンの中に「小さな専用のパソコン(コンテナ)」を作って、その中でアプリを動かす仕組みです。
Sailを使うと、PHP・MySQL・メール確認ツールなどが入ったコンテナがまとめて用意されます。
自分のパソコンにPHPやMySQLを直接インストールしなくていいのがうれしいところです。
今回Sailを選んだ理由は3つです。
- 公式の環境なので、MySQLとメール確認ツール(Mailpit)が最初からそろう
- 自分でDockerの設定ファイルを書くのは勉強になるけれど、それは仕上げの段階でやれば十分
- あとから中身を取り出して、自分好みに変えることもできる
まずは「動く環境を早く作って、アプリづくりに集中する」ことを優先しました。
手順1:プロジェクトを作る
Docker Desktop を起動した状態で、ターミナルで次のコマンドを実行します。
curl -s "https://laravel.build/backend?with=mysql,mailpit" | bash
backend… 作られるフォルダの名前ですwith=mysql,mailpit… 一緒に用意するもの。今回は MySQL と Mailpit(送ったメールをブラウザで確認できるツール)を指定しました
途中でMacのパスワードを聞かれます。
ファイルの権限を調整するためなので、入力して進めてOKです。最初はびっくりしますよね。
手順2:起動する前に .env を設定する
ここがこの記事でいちばん伝えたいポイントです。
プロジェクトができたら、すぐに起動せず、先に .env を設定します。
理由は、MySQLのコンテナは、最初に起動したときにしかデータベースを作らないからです。
先に起動してしまうと、あとから .env でデータベース名を変えても、そのデータベースは存在しないので接続エラーになります。
もしやってしまった場合は、コンテナをデータごと削除して作り直すことになります(中のデータは消えます)。
最初に決めておけば避けられるので、起動前に設定しておくのがおすすめです。
今回はこのように設定しました(関係するところだけ抜き出しています)。
APP_NAME="備品在庫管理システム"
APP_TIMEZONE=Asia/Tokyo
APP_URL=http://localhost
APP_LOCALE=ja
APP_FALLBACK_LOCALE=en
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=inventory
DB_USERNAME=sail
DB_PASSWORD=password
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_ja_0900_as_cs
SESSION_DRIVER=database
SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost:5173
FRONTEND_URL=http://localhost:5173
タイムゾーンや言語のほかに、意味を知っておきたい設定が3つあります。
| 設定 | 何のため? |
|---|---|
DB_COLLATION=utf8mb4_ja_0900_as_cs | 文字の比べ方のルールです。最後の _cs は「大文字と小文字を区別する」という意味。備品コードの AB-01 と ab-01 を別のものとして扱いたかったので、こうしました |
SESSION_DRIVER=database | ログイン状態(セッション)をデータベースに保存します。Laravel 11以降は最初からこの設定になっているので、そのまま使っています(Laravel 10まではファイルに保存するのが初期設定でした)。あとで出てくるエラーの原因になるので、覚えておいてください |
SANCTUM_STATEFUL_DOMAINS=localhost:5173 | React(Vite)の開発用サーバーのアドレスです。ここからの通信を「自分の画面からの通信」として扱い、ログイン状態を引き継げるようにします |
大文字と小文字を区別すると、メールアドレスで困る
大文字と小文字を区別する設定にはデメリットもあります。User@example.com と user@example.com も別のものとして扱われるので、そのままだと同じ人が2回登録できてしまいます。
そこで、メールアドレスは保存する前に小文字にそろえることにしました。
1つの設定を決めると、別の場所に影響が出る。
設定の意味を知っておくと、こういうことに先に気づけます。
手順3:起動する
.env を保存したら、いよいよ起動です。
cd backend
./vendor/bin/sail up -d
-d は「裏側で動かし続ける」という意味です。
初回はコンテナの準備に5〜10分ほどかかりました。
💡 毎回
./vendor/bin/sailと打つのは長いので、sailだけで動くように設定(エイリアス)する方法もあります。
ただ、私はLaravelの開発に慣れるまではあえて設定せず、毎回フルで打っています。
何を動かしているのかが見えるので、今はこのほうが分かりやすいです。
ハマったこと:sessionsテーブルが見つからない
起動できたので、ブラウザで http://localhost を開いてみると……500エラーになりました。
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'inventory.sessions' doesn't exist
「inventory データベースに sessions テーブルがない」というエラーです。
原因:テーブルを作るコマンドをまだ実行していなかった
手順2で、ログイン状態をデータベースに保存する設定(SESSION_DRIVER=database)にしました。
Laravelはトップページを表示するだけでもログイン状態の準備を始めるので、その保存先のテーブルが必要になります。
でも、テーブルを作るコマンド(マイグレーション)をまだ実行していませんでした。次のコマンドで解決です。
./vendor/bin/sail artisan migrate
sessionsテーブルはどこで作られる?
ここで1つ分かったことがあります。
最近のLaravel(11以降)では、sessions テーブルはユーザーのテーブルと同じファイルの中で作られます。
database/migrations/0001_01_01_000000_create_users_table.php
├─ users
├─ password_reset_tokens
└─ sessions ← ここ
「セッション用のマイグレーションファイルはどこ?」と探しても、ファイル名に sessions が入っていないので見つからないんです。
✅ ちなみに、このエラーはいい知らせでもありました。エラーに
inventoryというデータベース名が出ているということは、手順2で設定したデータベースにちゃんと接続できている証拠です。
エラーメッセージは、どこまでうまくいっているかの手がかりにもなります。
手順4:APIとSanctumを入れる
office-hubは、画面をReactで作り、Laravelはデータをやり取りするAPIの役割をします。そのための準備です。
./vendor/bin/sail artisan install:api
./vendor/bin/sail artisan config:publish cors
install:api… API用のルート(URLの割り当て)を書くファイルroutes/api.phpを作り、ログイン機能のライブラリ Laravel Sanctum を入れますconfig:publish cors… 別のアドレスからの通信を許可する設定ファイルconfig/cors.phpを取り出します
Laravel 11以降は、この2つのファイルは最初は存在しません。
必要な人だけコマンドで作る形になっています。
「マイグレーションを実行しますか?」には yes
install:api を実行すると、途中でこう聞かれます。
One new database migration has been published.
Would you like to run all pending database migrations? (yes/no) [yes]:
これは personal_access_tokens というテーブルを作るかどうかの質問です。
このテーブルは、スマホアプリなどで使うトークン方式のログインのためのもので、今回使う方式(次の手順で説明します)では実は使いません。
それでも yes にしました。
- 実行していないマイグレーションを残したくない … noにしても、次にマイグレーションを実行したときに結局作られます。「わざと残しているのか、忘れているのか」が分からない状態になるのを避けたかったためです
- あとで使うかもしれない … 将来、棚卸し用のタブレットなどからAPIを使いたくなったら、そのまま使えます。空のテーブルが1つ増えるだけなので、損はほとんどありません
手順5:React画面からログインできるようにする
ログインの方式は、SanctumのSPA認証を選びました。ログイン状態をCookieで管理する方式です。
| 方式 | ログイン情報の保存場所 | 安全性 |
|---|---|---|
| トークン方式 | ブラウザの localStorage | 画面に悪意のあるスクリプトを仕込まれると(XSS)、トークンごと盗まれる |
| SPA認証(採用) | HttpOnly のCookie | JavaScriptから読めないので、スクリプトに盗まれにくい |
画面とAPIを同じドメインで動かす前提なので、Cookie方式の弱点(別のドメインをまたぐと設定が面倒)も問題になりません。
SPA認証を有効にするには、2つのファイルを編集します。
bootstrap/app.php
->withMiddleware(function (Middleware $middleware): void {
$middleware->statefulApi();
})
この1行で、APIでもログイン状態(セッション)を使えるようになります。SPA認証のいちばん大事なところです。
config/cors.php
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_origins' => [env('FRONTEND_URL', 'http://localhost:5173')],
'supports_credentials' => true,
paths… 通信を許可するURLallowed_origins… 通信を許可する相手。.envのFRONTEND_URL(Reactの開発サーバー)を読み込んでいますsupports_credentials… Cookieのやり取りを許可するかどうか
⚠️ 公式ドキュメントでは、SPA認証を使うときは
supports_credentialsをtrueにして、Access-Control-Allow-Credentialsというヘッダーを返すように案内されています。
画面とAPIのアドレスが違う構成では、これを忘れるとCookieを使ったログインがうまくいきません。
ここまでで、開発環境の準備は完了です。実際にReactの画面からログインするところは、もう少し先の回で書きます。
この時点のコードは、GitHubの phase-1 タグで見られます。
まとめ
- Laravel Sailを使うと、Laravel+MySQL+Mailpitの環境をコマンド1つで作れる
.envは最初の起動の前に設定する。MySQLのデータベースは最初の起動のときにしか作られない- 大文字と小文字を区別する設定にしたら、メールアドレスは小文字にそろえて保存する必要が出てきた
sessionsテーブルがないエラーはmigrateで解決。Laravel 11以降はユーザーのテーブルと同じファイルで作られる- React画面との認証はCookie方式のSPA認証。
statefulApi()とsupports_credentials => trueを忘れない
次回の#2では、部署・カテゴリ・保管場所といったマスタのテーブルを作ります。
#0で予告した「UNIQUE制約がNULLのときに効かない」問題にも、ここで向き合います。
Laravelをはじめて触る方は、Laravel開発の始め方|初心者向けの初期設定まとめもあわせてどうぞ。
私はふだん製造業で働きながら、WordPressを中心にWebサイトの制作をしています。
これまでの制作実績はポートフォリオにまとめています。
office-hubのコードはGitHubで公開しています。

