はじめに
Laravel 10をLaravel Sail(Docker)で学習していると、「phpMyAdminでDBを確認したい」という場面が出てきます。
ところが、いざ設定しようとすると次のような壁に当たりがちです。
-
docker-compose.ymlが見当たらない - ポートが競合してLaravelが起動しない
-
500 Internal Server Errorが出てブラウザで確認できない -
storageやbootstrap/cacheの権限でエラーが出る
本記事では、実際にこれらのエラーを踏んで解決した手順をそのまま紹介します。
Dockerに慣れていない方でも原因と対処がわかるよう、1つずつ丁寧に説明します。
環境
| 項目 | バージョン / 内容 |
|---|---|
| OS | Windows 11 + WSL2 Ubuntu |
| Docker | Docker Desktop |
| PHP フレームワーク | Laravel 10 |
| 開発環境 | Laravel Sail |
| DB | MySQL |
| GUIツール | phpMyAdmin |
| プロジェクト | ~/projects/laravel10-project |
最終的なポート構成は以下のとおりです。
| サービス | URL / 接続先 |
|---|---|
| Laravel 本体 | http://localhost:8080 |
| phpMyAdmin | http://localhost:8081 |
| MySQL 外部接続 | localhost:3307 |
docker-compose.yml ではなく compose.yaml を編集する
「Laravelの教科書 バージョン10」などの書籍では docker-compose.yml を編集すると説明されていますが、Laravel Sail環境では compose.yaml というファイルが使われている場合があります。
プロジェクトルートを確認してみましょう。
ls ~/projects/laravel10-project
docker-compose.yml が見当たらず compose.yaml が存在している場合は、compose.yaml を編集すれば問題ありません。
Docker Compose では compose.yaml / compose.yml が標準的なファイル名として扱われ、後方互換として docker-compose.yaml / docker-compose.yml もサポートされています。両方が存在する場合は標準の compose.yaml が優先されます。Laravel Sail はデフォルトで compose.yaml を生成するため、今回は compose.yaml を使います。
.env にポート設定を追加する
まず .env を確認します。
grep -E "APP_PORT|FORWARD_DB|PHPMYADMIN_PORT|WWWUSER|WWWGROUP" ~/projects/laravel10-project/.env
APP_PORT と FORWARD_DB_PORT はすでに存在しているはずです。
今回は PHPMYADMIN_PORT と、権限ズレ対策のための WWWUSER / WWWGROUP を追記します。
APP_PORT=8080
FORWARD_DB_PORT=3307
PHPMYADMIN_PORT=8081
WWWUSER=1000
WWWGROUP=1000
WWWUSER / WWWGROUP に設定する値は、WSL2上で以下のコマンドで確認できます。
id -u # → 1000(例)
id -g # → 1000(例)
compose.yaml に phpMyAdmin を追加する
compose.yaml を開き、services: 配下にある他のサービスと並べて phpmyadmin を追加します。
phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- '${PHPMYADMIN_PORT:-8081}:80'
environment:
PMA_HOST: mysql
PMA_PORT: 3306
depends_on:
- mysql
networks:
- sail
ポイント:PMA_HOST: mysql について
PMA_HOST には、Laravel Sail の MySQL サービス名である mysql を指定します。
phpMyAdmin はこの名前を使ってコンテナ内のネットワーク越しに MySQL へ接続するため、ホスト名は localhost ではなく mysql になります。
ログイン情報はブラウザのログイン画面で入力します(後述)。
セキュリティメモ
phpMyAdmin は便利なツールですが、外部公開は避けるのが基本です。今回の設定では8081に公開していますが、Docker 上では0.0.0.0:8081->80/tcpのように表示されます。環境によっては同一ネットワーク内の他の端末から到達できる可能性があるため、外部公開したくない場合は127.0.0.1:${PHPMYADMIN_PORT:-8081}:80のように localhost のみに限定すると安全です。本番環境では phpMyAdmin を公開しない方針が安全です。
コンテナを起動する
設定が完了したら、コンテナを起動します。
# sail エイリアスが設定済みの場合
sail up -d
# エイリアスが未設定の場合
./vendor/bin/sail up -d
エイリアス設定について
~/.bashrcまたは~/.zshrcにalias sail='./vendor/bin/sail'を追加しておくと便利です。
設定変更後、古いコンテナが残っている場合は一度停止してから再起動します。
sail down
sail up -d
ポート設定が古いコンテナに残ったまま反映されない場合は、強制再作成を行います。
sail down
docker compose up -d --force-recreate
Laravel と phpMyAdmin の表示確認
ポートの確認
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
正常であれば以下のように表示されます。
NAMES STATUS PORTS
laravel10-project-laravel.test-1 Up 0.0.0.0:8080->80/tcp, 0.0.0.0:5173->5173/tcp
laravel10-project-phpmyadmin-1 Up 0.0.0.0:8081->80/tcp
laravel10-project-mysql-1 Up 0.0.0.0:3307->3306/tcp
Laravel の疎通確認
curl -I http://localhost:8080
正常時:
HTTP/1.1 200 OK
ブラウザで確認
| サービス | URL |
|---|---|
| Laravel | http://localhost:8080 |
| phpMyAdmin | http://localhost:8081 |
phpMyAdmin のログイン情報は .env の DB 設定に合わせます。
サーバー名 : mysql
ユーザー名 : .env の DB_USERNAME に合わせる
パスワード : .env の DB_PASSWORD に合わせる
ハマりポイント
1. Laravel 本体と phpMyAdmin のポート競合
最初、phpMyAdmin のポート設定を以下のように書いてしまいました。
# NG:Laravel 本体と競合する
ports:
- 8080:80
Laravel 本体も .env の APP_PORT=8080 で 8080 を使っているため、起動時に競合してエラーになりました。
修正後:
ports:
- '${PHPMYADMIN_PORT:-8081}:80'
.env に PHPMYADMIN_PORT=8081 を追加することで競合を解消できます。
${PHPMYADMIN_PORT:-8081} という書き方は、「変数がなければデフォルト値 8081 を使う」という意味です。
2. docker ps で 8080 が公開されていない
.env と compose.yaml を正しく書いたはずなのに、docker ps の結果が次のようになっていました。
# NG:ホスト側のポートが公開されていない
80/tcp, 5173/tcp
本来は以下のようになるはずです。
# OK:8080 に公開されている
0.0.0.0:8080->80/tcp
原因:設定変更前に作成されたコンテナが古い情報のまま動いていました。
対処:コンテナを強制再作成します。
sail down
docker compose up -d --force-recreate
3. 500 Internal Server Error
ポート問題を解消した後、次は curl -I http://localhost:8080 が HTTP/1.1 500 Internal Server Error になりました。
レスポンスボディを確認します。
curl -s http://localhost:8080 | head -n 40
エラー内容:
The stream or file "/var/www/html/storage/logs/laravel.log" could not be opened
in append mode: Permission denied
file_put_contents(/var/www/html/storage/framework/sessions/...):
Failed to open stream: Permission denied
Laravel がログやセッションファイルを書き込めない状態でした。
原因は storage ディレクトリの権限(パーミッション・所有者)にあります。
4. storage / bootstrap/cache の権限修正
まず、書き込み権限を付与しました。
sudo chmod -R 775 storage bootstrap/cache
一時的に curl -I は 200 OK になりましたが、ブラウザ経由でセッションを書き込もうとすると再度エラーになりました。
原因を深掘り:コンテナ内の実行ユーザーを確認
sail exec laravel.test ps aux
sail /usr/bin/php ...
sail /usr/bin/php8.x -S 0.0.0.0:80 ...
PHP は sail ユーザー(UID=1000)で動いていました。
一方、ホスト側で storage 配下の権限・所有者が Laravel の実行ユーザーと合っておらず、セッションやログを書き込めない状態でした。
対処:所有者を UID/GID に合わせる
sudo chown -R 1000:1000 storage bootstrap/cache
これで Laravel 画面が正常に表示されました。
なぜ UID=1000 なのか
今回の環境では.envにWWWUSER=1000を設定していたため、コンテナ内のsailユーザーは UID=1000 として動作していました。ホスト側(WSL2)の自分のアカウントもid -uで確認した UID と一致させることで、chownによる所有者の統一が有効になります。
5. WWWUSER / WWWGROUP の設定
起動時に以下の警告が出ていました。
The "WWWGROUP" variable is not set. Defaulting to a blank string.
The "WWWUSER" variable is not set. Defaulting to a blank string.
.env に以下を追加することで解消しました。
WWWUSER=1000
WWWGROUP=1000
値は id -u / id -g で確認した自分の UID/GID を設定してください。
6. 他の Docker 環境とのポート競合(補足)
別途 Docker で LAMP 環境を構築しており、そちらの phpMyAdmin も 8080 を使っていたため、Laravel 本体の 8080 と競合していました。
LAMP 側の compose.yaml(または docker-compose.yml)を修正しました。
ports:
- "127.0.0.1:8082:80"
複数の Docker 開発環境を並行して使う場合は、ホスト側ポートを以下のように整理しておくとわかりやすいです。
| サービス | URL |
|---|---|
| Laravel 本体 | http://localhost:8080 |
| Laravel phpMyAdmin | http://localhost:8081 |
| LAMP phpMyAdmin | http://localhost:8082 |
まとめ
Laravel Sail 環境に phpMyAdmin を追加する手順と、実際に遭遇したエラーの原因・対処をまとめます。
| 問題 | 原因 | 対処 |
|---|---|---|
docker-compose.yml が見当たらない |
Sail は compose.yaml を使う |
compose.yaml を編集する |
| ポート競合でコンテナが起動しない | phpMyAdmin と Laravel 本体が同じポートを使っていた |
PHPMYADMIN_PORT=8081 に変更 |
docker ps でポートが公開されない |
古いコンテナが残っている |
--force-recreate で再作成 |
500 Internal Server Error |
storage の権限・所有者がズレていた |
chown -R 1000:1000 で修正 |
WWWUSER/WWWGROUP 警告 |
.env に未設定だった |
id -u / id -g で確認して追記 |
今回のように、エラーを ポートの問題 → コンテナの問題 → Laravel の問題 と1つずつ切り分けていくと、Docker 環境のトラブルシューティングがぐっとやりやすくなります。
「動かない」と感じたときは docker ps でポートを確認し、curl -I でHTTPレスポンスを確認し、本文を curl -s | head で覗いてみることを習慣にすると、原因の特定が早くなります。