Laravel×Dockerで開発環境を最短で安定させる:ローカル統一・再現性・速度を両立する構成
- 作成日 2026.02.27
- その他
Laravel開発をDocker化すると、PHP/Node/DB/Redisなどの依存関係をチームで統一でき、OS差異や「動く人と動かない人」を減らせる。重要なのは、ただコンテナを立てることではなく、コード編集・依存インストール・DBマイグレーション・キュー/スケジューラ・テスト・本番相当設定までを“毎回同じ手順”で回せる状態にすること。ここではLaravelとDocker Composeで、開発速度と再現性を両立する構成を組み立てる。
- 1. ゴール設定:Docker化で解決したい問題を先に固定する
- 2. 構成の基本:app / web / db / cache / queue を分けて考える
- 3. ディレクトリ設計:docker配下に設定を集約する
- 4. docker-compose.yml:全体のサービス定義(最小~実用)
- 5. PHP Dockerfile:拡張・Composer・ユーザー権限を最初に固める
- 6. Nginx設定:public配下・index.phpへのフォールバックを正しく
- 7. .envの整備:Docker向けにDBホストをサービス名にする
- 8. 初回セットアップ:ワンコマンドで起動→依存→キー生成→マイグレーション
- 9. ホットリロード:ViteをDockerで動かしてフロント開発を速くする
- 10. QueueとScheduler:開発でも“動く前提”で回しておく
- 11. ストレージ権限:storage と bootstrap/cache を確実に書ける状態にする
- 12. DB永続化とリセット:named volume運用と初期化手順
- 13. テストの回し方:同じコンテナでユニット/Featureを走らせる
- 14. 速度改善:遅いDockerを“開発速度が出るDocker”に寄せる
- 15. よくあるエラーと即チェック項目
- 16. まとめ:Laravel×Docker開発環境を“使える形”で固定する要点
ゴール設定:Docker化で解決したい問題を先に固定する
典型的な狙い:
・PHP/Composer/Nodeのバージョン差をゼロにする
・MySQL/PostgreSQL/Redisなどをワンコマンドで起動
・新メンバーが「clone→起動→動作確認」まで最短
・CIとローカルを同じ構成に寄せる
・本番との差分(拡張、ini、タイムゾーン、ロケール)を見える化する
ゴールが曖昧だと、Dockerは「遅い」「難しい」に寄りやすい。
構成の基本:app / web / db / cache / queue を分けて考える
開発でよく使う分割:
・app:PHP-FPM(Laravel本体)
・web:Nginx(またはCaddy)
・db:MySQL/PostgreSQL
・cache:Redis
・queue:queue worker(appと同イメージで別サービス)
・scheduler:cron(Laravel schedule:run を回す)
最小は app+db でも良いが、後で増やす前提で設計すると崩れにくい。
ディレクトリ設計:docker配下に設定を集約する
おすすめ例:
・docker/nginx/default.conf
・docker/php/Dockerfile
・docker/php/php.ini
・docker/mysql/initdb.d/
・docker/postgres/initdb.d/
Docker関連が散らばると、メンテが破綻しやすい。
docker-compose.yml:全体のサービス定義(最小~実用)
LaravelはPHP-FPM+Nginxが定番。DBとRedis、必要ならMailhogも足す。
version: "3.9"
services:
app:
build:
context: .
dockerfile: docker/php/Dockerfile
container_name: laravel_app
working_dir: /var/www
volumes:
- ./:/var/www
environment:
TZ: Asia/Tokyo
depends_on:
- db
- redis
web:
image: nginx:1.27-alpine
container_name: laravel_web
ports:
- "8080:80"
volumes:
- ./:/var/www
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
db:
image: mysql:8.4
container_name: laravel_db
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: laravel
MYSQL_USER: laravel
MYSQL_PASSWORD: secret
MYSQL_ROOT_PASSWORD: root
TZ: Asia/Tokyo
volumes:
- dbdata:/var/lib/mysql
redis:
image: redis:7-alpine
container_name: laravel_redis
ports:
- "6379:6379"
volumes:
dbdata:ポイント:
・ソースコードは volumes でマウント(編集→即反映)
・DBは named volume で永続化
・ポートは開発用に固定(8080など)
・TZを揃えてログ・日時ズレを防ぐ
PHP Dockerfile:拡張・Composer・ユーザー権限を最初に固める
Laravelでよく要る拡張:pdo_mysql、mbstring、intl、zip、gd、bcmath、opcache など。Composerを入れて、ホストとの権限問題も避ける。
# docker/php/Dockerfile
FROM php:8.3-fpm
ENV TZ=Asia/Tokyo
RUN apt-get update && apt-get install -y \
git unzip libzip-dev libicu-dev libpng-dev libjpeg-dev libfreetype6-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install pdo_mysql mbstring intl zip bcmath gd opcache \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Composer
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /var/www発生しやすい問題:
・拡張不足で Class "PDO" not found / ext-xxx is missing
・GD/Intlの依存ライブラリ不足
・権限問題で storage / bootstrap/cache に書けない
Nginx設定:public配下・index.phpへのフォールバックを正しく
Laravelは全リクエストをpublic/index.phpに流す。これが崩れると404祭りになる。
# docker/nginx/default.conf
server {
listen 80;
server_name _;
root /var/www/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass app:9000;
}
location ~* \.(css|js|png|jpg|jpeg|gif|svg|ico)$ {
expires 7d;
access_log off;
}
}.envの整備:Docker向けにDBホストをサービス名にする
Docker内では 127.0.0.1 ではなく、Composeのサービス名(db/redis)で接続する。
# .env(例)
APP_URL=http://localhost:8080
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=secret
CACHE_STORE=redis
REDIS_HOST=redis
REDIS_PORT=6379エラー発生条件:
・DB_HOSTがlocalhostのままで接続失敗
・APP_URLがズレて、URL生成やCSRFが崩れる
・キャッシュ/セッションドライバだけ本番寄りで、Redis未起動
初回セットアップ:ワンコマンドで起動→依存→キー生成→マイグレーション
手順を固定すると、チームが詰まらない。
# 起動
docker compose up -d --build
# Composerインストール
docker compose exec app composer install
# APP_KEY
docker compose exec app php artisan key:generate
# マイグレーション
docker compose exec app php artisan migrateホットリロード:ViteをDockerで動かしてフロント開発を速くする
フロントもDockerに載せると統一できるが、ホスト実行の方が速い場合もある。Dockerでやるならポート公開とhost指定が必要。
# 例:appコンテナ内で
docker compose exec app npm install
docker compose exec app npm run dev -- --host 0.0.0.0 --port 5173運用ポイント:
・Viteのポート(5173)をcomposeで公開する
・WS接続が必要なのでhost設定が重要
・Windows環境はファイル監視が遅いことがある(設定で改善)
QueueとScheduler:開発でも“動く前提”で回しておく
キューやスケジューラをローカルで回さないと、本番だけ壊れる。別サービスで立てると管理が楽。
# キューワーカー(手動実行でもOK)
docker compose exec app php artisan queue:work
# スケジューラ(開発ならrunでも可)
docker compose exec app php artisan schedule:run本格運用なら compose に queue / scheduler サービスを追加し、常時起動に寄せる。
ストレージ権限:storage と bootstrap/cache を確実に書ける状態にする
Laravelが書き込めないと、ログもキャッシュもセッションも壊れる。ホストOSとUID/GIDがズレると頻発する。
# まずは開発用に権限を整える例
docker compose exec app bash -lc "chmod -R 775 storage bootstrap/cache"
より堅くするなら、Dockerfileでユーザー作成+権限設計まで固定する。
DB永続化とリセット:named volume運用と初期化手順
DBを消す操作は事故りやすいので、手順を明文化する。
docker compose down -v
# DBは残してアプリだけ再起動
docker compose down
docker compose up -dテストの回し方:同じコンテナでユニット/Featureを走らせる
テストもDockerで統一すると、CIとの差が減る。
# PHPUnit / Pest(どちらでも)
docker compose exec app php artisan testDBを分けたい場合は test 用DBを別に用意し、.env.testing をDocker前提で作る。
速度改善:遅いDockerを“開発速度が出るDocker”に寄せる
効くポイント:
・依存(vendor/node_modules)をボリューム分離(OSによって体感が変わる)
・Composer/NPMのキャッシュを使う
・不要なサービスを起動しない(profiles)
・イメージのレイヤを整理してビルドを速くする
・Windows/MacのファイルI/O問題は、マウント方式やWSL2設定で大きく改善することがある
よくあるエラーと即チェック項目
・Cannot Connect to the Docker Daemon:Docker Desktop起動、権限、service状態
・Connection refused (DB/Redis):サービス名接続、depends_on、ポート、初期化待ち
・Permission denied (storage):UID/GID、chmod/chown、Dockerfileのユーザー
・404/502(Nginx):rootがpublicか、fastcgi_passがapp:9000か、try_files
・APP_KEY missing:key:generate未実行、.envの読み込み不備
まとめ:Laravel×Docker開発環境を“使える形”で固定する要点
・サービスを役割で分け、Composeで一括起動に寄せる
・DB/Redisの接続先はサービス名に統一
・DockerfileでPHP拡張とComposerを固定し、再現性を担保
・Nginxのpublic/try_filesを正しく設定
・キュー/スケジューラ/テストもローカルで回る前提にする
・速度と権限問題は早めに潰し、チーム手順をコマンドで統一する
-
前の記事
LaravelでOAuth2認証を導入・管理する:Passportでトークン発行から運用まで固める手順 2026.02.26
-
次の記事
記事がありません
コメントを書く