LaravelでWebアプリケーションを開発する際、環境構築のデファクトスタンダードとなっているのがDockerです。ホストPCの環境を汚さず、チーム全員で全く同一のPHPバージョンやデータベース構成を再現できるため、実務開発において必須のスキルといえます。
しかし、「DockerでLaravel環境を作る」と一口に言っても、Laravel公式の「Laravel Sail」を使う方法と、自前で「Dockerfileやcompose.yaml」を記述するカスタム構成の2つの選択肢があり、「どちらを選ぶべきか」「何が違うのか」で迷う方は少なくありません。
本記事では、Laravel 11 / 12 / 13およびPHP 8.3 / 8.4に対応した環境をもとに、「Laravel Sail」と「カスタムDocker Compose」の違いの徹底比較から、それぞれの具体的な構築手順、Vite連携、現場で頻発するエラーと解決策まで、実機検証済みのコードとともに徹底解説します。
Sail vs カスタムDocker Compose|違いと選び方【比較表】
まずは、Laravel Sailと自前Docker Composeの主要な違いを整理しましょう。
| 比較項目 | Laravel Sail(公式ツール) | カスタムDocker Compose(自前構築) |
|---|---|---|
| 概要 | Laravel公式が提供するDocker開発環境CLIラッパー | Dockerfileやcompose.yamlを自分で記述する構成 |
| 構築スピード | ◎ コマンド1発(数分で起動完了) | △ 各種設定ファイル(Nginx/PHP/DB)の記述が必要 |
| Dockerの知識 | ○ ほぼ不要(コンテナを意識せず使える) | △ Dockerfileやネットワーク、権限の知識が必要 |
| Webサーバー構成 | PHP組み込みサーバー / 単一コンテナ内包型 | Nginx + PHP-FPM 分離型(本番構成に準拠可能) |
| 日常のコマンド操作 | sail artisan ... など直感的で快適 |
docker compose exec app php artisan ... |
| カスタマイズ性 | △ Sailの既定構造に縛られる(publishで拡張可) | ◎ 拡張モジュールやミドルウェアを完全自由に設計可能 |
| 本番環境への流用 | × ローカル開発専用設計 | ◎ Dockerfileや設定を本番コンテナへ転用しやすい |
| おすすめの対象者 | ・Laravel初心者、個人開発者 ・手軽に素早く開発を始めたい方 |
・実務のチーム開発や本番環境を意識したい方 ・NginxやPHP拡張を細かく制御したい方 |
どちらを選ぶべきかの判断基準
- 「まずは手軽にLaravelを動かしたい」「Dockerの細かい設定で消耗したくない」場合:迷わずLaravel Sailを選びましょう。公式サポートされており、MySQL、Redis、Mailpitなどの連携もコマンド1つで完結します。
- 「NginxとPHP-FPMを分けた本番に近い構成を学びたい」「特定のPHP拡張やライブラリを追加したい」場合:カスタムDocker Composeが適しています。サーバーアーキテクチャの理解が深まり、AWS ECSやGCP Cloud Run、Kubernetesなどのコンテナ本番デプロイにも応用が効きます。
動作検証環境
本記事で紹介するコードと手順は、以下の最新環境で動作確認を行っています。
- Laravel: 13.x / 12.x / 11.x
- PHP: 8.3 / 8.4
- Docker Engine: v27.x 以降 / Docker Desktop 4.x
- Docker Compose: v2.x(
compose.yaml形式) - Database: MySQL 8.4 / 8.0
【注意】Docker Compose v2とcompose.yamlについて
従来のdocker-compose(ハイフン付きのv1)はサポートが終了しており、現在はプラグイン型のdocker compose(スペース区切り・v2)が標準です。また、設定ファイル名もdocker-compose.ymlからcompose.yamlが推奨規格となっています(Laravel Sailも最新版ではcompose.yamlを生成します)。
方法1:Laravel Sailで最速セットアップ(公式推奨)
Laravel Sailは、ホストマシンにPHPやComposer、Node.jsを一切インストールしていなくても、Dockerさえあれば一瞬でフルスタック環境を立ち上げられる公式開発環境です。
新規プロジェクトを作成する場合
ターミナルで以下のcurlコマンドを実行するだけで、Sailが組み込まれた新規Laravelプロジェクトが作成されます。
# MySQL、Redis、Mailpitを含んだ「example-app」を作成
curl -s "https://laravel.build/example-app?with=mysql,redis,mailpit" | bash
# プロジェクトディレクトリに移動
cd example-app
# バックグラウンドでコンテナ起動
./vendor/bin/sail up -d
起動後、ブラウザで http://localhost にアクセスすると、Laravelの初期画面が表示されます。
既存のLaravelプロジェクトにSailを追加する場合
すでに存在するプロジェクトにSailを導入する場合は、Composerでパッケージを追加してインストールコマンドを実行します。
# 1. Sailを開発依存としてインストール
composer require laravel/sail --dev
# 2. compose.yamlと設定を生成
php artisan sail:install --with=mysql,redis,mailpit
# 3. コンテナを起動
./vendor/bin/sail up -d
# 4. マイグレーションを実行
./vendor/bin/sail artisan migrate
詳しいインストールオプションや対話形式での設定については、sail:install — Sailをインストールするコマンドで詳しく解説しています。
Sailで生成されるcompose.yamlの仕組み
sail:installを実行すると、プロジェクト直下にcompose.yamlが生成されます。その主要な構造は以下のようになっています。
services:
laravel.test:
build:
context: './vendor/laravel/sail/runtimes/8.4'
dockerfile: Dockerfile
args:
WWWGROUP: '${WWWGROUP}'
image: 'sail-8.4/app'
ports:
- '${APP_PORT:-80}:80'
- '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
environment:
WWWUSER: '${WWWUSER}'
LARAVEL_SAIL: 1
volumes:
- '.:/var/www/html'
networks:
- sail
depends_on:
- mysql
- redis
mysql:
image: 'mysql:8.4'
ports:
- '${FORWARD_DB_PORT:-3306}:3306'
environment:
MYSQL_DATABASE: '${DB_DATABASE}'
MYSQL_USER: '${DB_USERNAME}'
MYSQL_PASSWORD: '${DB_PASSWORD}'
volumes:
- 'sail-mysql:/var/lib/mysql'
networks:
- sail
redis:
image: 'redis:alpine'
volumes:
- 'sail-redis:/data'
networks:
- sail
networks:
sail:
driver: bridge
volumes:
sail-mysql:
driver: local
sail-redis:
driver: local
Sailの特徴は、laravel.testコンテナの中にPHP CLI、組み込みWebサーバー、Node.js、Composer、Supervisordなどがすべてパッケージ化されている点です。これにより、Webサーバー用コンテナを別途立てる必要がなく、シンプルな1コンテナ構成で動作します。
よく使うSailコマンドとエイリアス設定
毎回./vendor/bin/sailと入力するのは手間がかかるため、シェルの設定ファイル(~/.bashrcや~/.zshrc)にエイリアスを登録しておきましょう。
alias sail='[ -f sail ] && sh sail || sh vendor/bin/sail'
設定を反映(source ~/.zshrc)させると、以降はsailコマンドが使えます。
# コンテナの起動・停止
sail up -d
sail down
# Artisanコマンドの実行
sail artisan migrate
sail artisan make:model Post -m
# Composer / NPM の実行
sail composer require laravel/breeze --dev
sail npm install
sail npm run dev
# データベースCLIへのログイン
sail mysql
# コンテナ内シェルへ入る
sail shell
Sailのさらに詳しいコマンドや活用術については、Laravel Sailとは?初心者向け導入・起動停止・よく使うコマンド・Dockerとの関係を徹底解説をご覧ください。
方法2:カスタムDocker Composeで構築する(LEMP構成)
実務開発や本番環境へのデプロイを想定する場合、Webサーバー(Nginx)、アプリケーションサーバー(PHP-FPM)、データベース(MySQL)を独立したコンテナとして分離するLEMPスタック構成が標準的です。
ディレクトリ構成
プロジェクトルートにdockerディレクトリを作成し、各設定ファイルを整理して配置します。
laravel-docker-app/
├── docker/
│ ├── nginx/
│ │ └── default.conf # Nginxのバーチャルホスト設定
│ └── php/
│ ├── Dockerfile # PHP-FPM用ビルド定義
│ └── php.ini # PHPの動作設定
├── compose.yaml # Docker Compose構成ファイル
├── .env # 環境変数設定
├── app/
├── bootstrap/
├── config/
├── public/
├── routes/
├── storage/
└── composer.json
1. Dockerfileの作成(docker/php/Dockerfile)
PHP 8.3 / 8.4のFPM Alpineイメージをベースに、Laravelの動作に必要な拡張モジュール(PDO MySQL、BCMath、GD、Zip、OPcache等)をインストールし、Composerをマルチステージビルドで組み込みます。
FROM php:8.3-fpm-alpine
# システム依存パッケージのインストール
RUN apk add --no-cache \
git \
curl \
zip \
unzip \
libzip-dev \
libpng-dev \
libjpeg-turbo-dev \
freetype-dev \
oniguruma-dev \
icu-dev \
linux-headers
# PHP拡張モジュールのインストール
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) \
pdo_mysql \
mbstring \
zip \
bcmath \
gd \
intl \
opcache
# Composerの公式イメージからバイナリをコピー
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
# 作業ディレクトリの設定
WORKDIR /var/www
# コンテナ起動コマンド
CMD ["php-fpm"]
2. PHP設定ファイルの作成(docker/php/php.ini)
ローカル開発に適したメモリ上限やファイルアップロードサイズを設定します。
[PHP]
memory_limit = 512M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 60
display_errors = On
display_startup_errors = On
error_reporting = E_ALL
default_charset = "UTF-8"
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.language = "Japanese"
3. Nginx設定ファイルの作成(docker/nginx/default.conf)
NginxからPHP-FPMコンテナ(app:9000)へリクエストを転送し、Laravelのpublic/index.phpへルーティングします。
server {
listen 80;
server_name localhost;
root /var/www/public;
index index.php index.html;
charset utf-8;
# すべてのリクエストをLaravelのフロントコントローラーへ渡す
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# ファビコンとrobots.txtのログを抑制
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
# エラーページ設定
error_page 404 /index.php;
# PHP-FPMへのプロキシ設定
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
}
# .envや.gitなどの隠しファイルへのアクセスを拒否
location ~ /\.(?!well-known).* {
deny all;
}
}
Nginxの設定についてより深く知りたい方は、LaravelとNginxの設定方法:初心者でも簡単に環境構築する方法も参考にしてください。
4. compose.yamlの作成
app(PHP-FPM)、web(Nginx)、db(MySQL)の3つのコンテナを連携させる定義をプロジェクトルートに記述します。
services:
app:
build:
context: .
dockerfile: ./docker/php/Dockerfile
working_dir: /var/www
volumes:
- ./:/var/www
- ./docker/php/php.ini:/usr/local/etc/php/conf.d/custom.ini
networks:
- laravel-net
depends_on:
- db
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./:/var/www
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
networks:
- laravel-net
depends_on:
- app
db:
image: mysql:8.4
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: ${DB_DATABASE:-laravel}
MYSQL_USER: ${DB_USERNAME:-laravel}
MYSQL_PASSWORD: ${DB_PASSWORD:-secret}
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD:-secret}
volumes:
- db_data:/var/lib/mysql
networks:
- laravel-net
networks:
laravel-net:
driver: bridge
volumes:
db_data:
driver: local
5. .envファイルのデータベース設定
コンテナ間の通信では、データベースのホスト名(DB_HOST)に127.0.0.1やlocalhostではなく、Docker Composeのサービス名である「db」を指定します。
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=secret
データベース接続の基本や設定項目については、LaravelとMySQLの接続設定ガイドで詳しく解説しています。
6. 起動と初期セットアップ手順
設定ファイルが揃ったら、コンテナをビルド・起動し、アプリケーションの初期化を行います。
# 1. コンテナのビルドと起動
docker compose up -d --build
# 2. Composerパッケージのインストール
docker compose exec app composer install
# 3. アプリケーションキーの生成
docker compose exec app php artisan key:generate
# 4. ディレクトリ権限の修正(書き込みエラー対策)
docker compose exec app chmod -R 775 storage bootstrap/cache
docker compose exec app chown -R www-data:www-data storage bootstrap/cache
# 5. マイグレーションの実行
docker compose exec app php artisan migrate
ブラウザで http://localhost:8080 にアクセスし、Laravelの初期画面が表示されれば環境構築完了です。
Docker環境でのVite(フロントエンド開発)設定
LaravelのフロントエンドビルドツールであるViteをDocker上で動かす場合、ホットモジュールリプレイスメント(HMR)用のポート5173を開放し、Vite設定を調整する必要があります。
1. compose.yamlにポート5173を追加
compose.yamlのappサービスにポートフォワーディングを追加します。
app:
# ... 他の設定 ...
ports:
- "5173:5173"
2. vite.config.jsの設定修正
ホストマシンのブラウザからコンテナ内のViteサーバーへWebSocket接続できるよう、serverオプションを追記します。
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.js'],
refresh: true,
}),
],
server: {
host: '0.0.0.0', // コンテナ外からのアクセスを許可
port: 5173,
hmr: {
host: 'localhost', // ブラウザからのHMR接続先
},
},
});
これで、docker compose exec app npm run dev(Sailならsail npm run dev)を実行すると、BladeファイルやCSS/JSの変更がブラウザに即座にホットリロードされます。
Docker + Laravelで初心者がつまずくエラーと解決策
| エラー現象・メッセージ | 原因 | 具体的な解決策 |
|---|---|---|
Permission denied / 500エラーThe stream or file "...laravel.log" could not be opened: failed to open stream: Permission denied |
ホストとコンテナ(www-data)のユーザーUIDの不一致により、storage/やbootstrap/cache/への書き込みが拒否されている |
docker compose exec app chmod -R 775 storage bootstrap/cache および docker compose exec app chown -R www-data:www-data storage bootstrap/cache を実行する |
データベース接続エラーSQLSTATE[HY000] [2002] Connection refused |
.envのDB_HOSTが127.0.0.1やlocalhostのままになっている(コンテナ自身を指してしまう) |
.envのDB_HOSTをDockerサービス名(カスタムならdb、Sailならmysql)に変更する |
ポート競合エラーBind for 0.0.0.0:80 failed: port is already allocated |
ホストマシン上の既存Webサーバー(Apache/Nginx)や別のコンテナがポート80/3306を使用中 | compose.yamlのホスト側ポートを8080:80や33060:3306に変更する(Sailなら.envでAPP_PORT=8080を指定) |
| Windows (WSL2) で動作が異常に重い | プロジェクトファイルがWindows側のCドライブ(/mnt/c/...)に置かれている |
WSL2内のLinuxネイティブ領域(/home/ユーザー名/...)にプロジェクトを作成・移動する |
コンテナ起動時にマイグレーションが失敗するSQLSTATE[HY000] [2002] php_network_getaddresses |
MySQLコンテナの初期化完了前にLaravelのマイグレーションが走ってしまった | MySQLのヘルスチェック(healthcheck)を設定するか、MySQLコンテナが完全起動するまで数秒待ってからmigrateを実行する |
まとめと関連記事
Dockerを使ったLaravel環境構築は、用途とスキルレベルに応じて最適な手段を選ぶことが成功の鍵です。
- 最速で開発を始めたい・Dockerに詳しくない → Laravel Sail(
curl -s "https://laravel.build/app" | bash) - 本番環境に近いマルチコンテナ構成を学びたい・自由にカスタムしたい → カスタムDocker Compose(Nginx + PHP-FPM + MySQL)
- 権限エラー(Permission denied)が出たら →
storageとbootstrap/cacheの権限(775 /www-data)を修正 - DB接続に失敗したら →
DB_HOSTがコンテナサービス名(db/mysql)になっているか確認
どちらの方法を選んでも、Dockerを活用することで環境差異によるトラブルをなくし、再現性の高い快適な開発環境を手に入れることができます。

コメント