2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WSL + Docker + Laravel SailでLaravel10環境を構築する方法(Composerコンテナ使用)

2
Last updated at Posted at 2026-04-27

はじめに

Laravel Sail の環境構築では laravel.build を使う方法がよく紹介されています。しかしこの方法ではLaravelのバージョンを固定できません。本記事では Docker コンテナ内の Composer を使用して Laravel10 を確実にインストールする方法を解説します。

環境

  • Windows 11
  • WSL2 (Ubuntu)
  • Docker Desktop(Windowsにインストール)
  • /etc/wsl.conf でデフォルトユーザー設定済み
    (WSL起動時にrootではなく通常ユーザーでログインする設定)

目次


1. 前提条件

  • Docker Desktopが起動していること
  • WSLにcomposerは不要(Dockerコンテナ内で実行するため)

注意curl -s https://laravel.build/... | bash はLaravelのバージョン指定ができない。そのため実行時点のテンプレートに依存し、最新メジャーバージョン(2026/07/14時点ではLaravel 13)がインストールされる可能性がある。Laravel 10を確実に使用したい場合は composer create-project でバージョン指定する。
※Laravel Sail自体にバージョン制限はなく、laravel.build経由のプロジェクト作成時に最新バージョンがインストールされる点に注意。


2. プロジェクトの作成

作業ディレクトリを作成して移動する。

mkdir -p ~/projects
cd ~/projects

2-1. Dockerコンテナ内のComposerでLaravel 10を作成する

Laravelプロジェクトの作成、Sailの導入、Sail構成の生成は、失敗箇所を切り分けられるように分けて実行する。

docker run --rm \
  -u "$(id -u):$(id -g)" \
  -e COMPOSER_HOME=/tmp/composer \
  -v "$(pwd)":/opt \
  -w /opt \
  laravelsail/php82-composer:latest \
  composer create-project laravel/laravel:^10.0 laravel10-project

正常に完了したら、作成されたプロジェクトへ移動する。

cd laravel10-project

2-2. Laravel Sailの導入状況を確認する

Laravelのプロジェクトテンプレートによっては、Sailが最初から開発用依存関係に含まれている場合がある。

grep '"laravel/sail"' composer.json

laravel/sailが表示されなかった場合だけ、次のコマンドでSailを追加する。

docker run --rm \
  -u "$(id -u):$(id -g)" \
  -e COMPOSER_HOME=/tmp/composer \
  -v "$(pwd)":/opt \
  -w /opt \
  laravelsail/php82-composer:latest \
  composer require laravel/sail --dev

2-3. MySQLを使用するSail構成を生成する

docker run --rm \
  -u "$(id -u):$(id -g)" \
  -e COMPOSER_HOME=/tmp/composer \
  -v "$(pwd)":/opt \
  -w /opt \
  laravelsail/php82-composer:latest \
  php artisan sail:install --with=mysql

成功すると、プロジェクト直下にdocker-compose.ymlまたはcompose.yamlが生成される。

ls -la

コマンドの説明

オプション・引数 説明
--rm コマンド終了後に一時コンテナを削除する
-u "$(id -u):$(id -g)" コンテナ内で生成されるファイルの所有者をWSL側のユーザーに合わせ、root所有になることを防ぐ
-e COMPOSER_HOME=/tmp/composer Composerのホームディレクトリを書き込み可能な/tmp/composerへ設定する
-v "$(pwd)":/opt WSL側の現在のディレクトリを、コンテナ内の/optへマウントする
-w /opt コンテナ内の作業ディレクトリを/optに設定する
laravelsail/php82-composer:latest PHP 8.2とComposerを含むLaravel SailのComposerイメージを使用する
composer create-project Composerパッケージから新しいプロジェクトを作成する
laravel/laravel:^10.0 Laravelアプリケーションスケルトンを10系に固定する
laravel10-project 作成するプロジェクトのディレクトリ名
composer require laravel/sail --dev Sailが含まれていない場合に、開発用依存関係として追加する
php artisan sail:install --with=mysql MySQLを含むSailのCompose構成を生成する

[!NOTE]
-u "$(id -u):$(id -g)"を指定しても、.envWWWUSERWWWGROUPが自動追加されるわけではない。

このオプションは、今回使用する一時的なComposerコンテナが生成するファイルの所有者を、WSL側のユーザーへ合わせるための指定である。

WWWUSERWWWGROUPはSailコンテナのビルドや実行時に使われる別の値であり、必要な場合は後述の設定で追加する。

[!IMPORTANT]
composer create-projectcomposer requiresail:install&&で連結すると、途中で異常終了した場合に後続処理が実行されない。

また、プロジェクトやvendorディレクトリだけが途中まで作成され、どこまで成功したのか判断しにくくなることがある。本記事では、処理を分けて正常終了を確認してから次へ進む。


3. .envの設定

既存のLAMP環境とポートが重複しないように、Laravel Sail側のWeb・MySQL外部接続ポートを変更する。
phpMyAdminを後から追加する場合に備えて、phpMyAdmin用のポートもあわせて設定しておく。

cd ~/projects/laravel10-project
sed -i 's/^APP_PORT=.*/APP_PORT=81/' .env
sed -i 's/^FORWARD_DB_PORT=.*/FORWARD_DB_PORT=3307/' .env
sed -i 's/^PHPMYADMIN_PORT=.*/PHPMYADMIN_PORT=8082/' .env

sed は対象行が存在する場合のみ置換される。存在しない場合は、下記の追記コマンドを使用すること。
※ phpMyAdminサービスを追加する手順は別記事で扱っている。本記事では、追加済みのphpMyAdminコンテナのポートを 8082 に変更する前提で記載している。

.envAPP_PORTFORWARD_DB_PORTPHPMYADMIN_PORT が存在しない場合は以下で追記する:

echo 'APP_PORT=81' >> .env
echo 'FORWARD_DB_PORT=3307' >> .env
echo 'PHPMYADMIN_PORT=8082' >> .env

WWWUSER / WWWGROUP の追加

Laravel SailのDockerfileビルド時には WWWUSER / WWWGROUP という環境変数が参照される。これらが .env に存在しない場合、docker compose build --no-cache 実行時に警告が出て、ビルドが失敗することがある(詳細はトラブルシューティング参照)。

プロジェクト作成時の -u "$(id -u):$(id -g)" はファイル所有者対策であり、WWWUSER / WWWGROUP とは別の指定である。以下のコマンドで .env に追記する:

echo "WWWUSER=$(id -u)" >> .env
echo "WWWGROUP=$(id -g)" >> .env

id -u / id -g の結果は環境によって異なる。多くのWSL環境では 1000 になることが多いが、固定値として記述せず、必ずコマンドで取得すること。

確認:

grep -E "APP_PORT|FORWARD_DB_PORT|PHPMYADMIN_PORT|WWWUSER|WWWGROUP" .env

以下のように表示されればOK:

APP_PORT=81
FORWARD_DB_PORT=3307
PHPMYADMIN_PORT=8082
WWWUSER=1000
WWWGROUP=1000

ポート構成

LAMP環境 Laravel 10 Sail
Web :80 :81
phpMyAdmin :8081 :8082
MySQL ホスト公開なし :3307

4. Laravel Sailを起動

./vendor/bin/sail up -d

起動確認:

./vendor/bin/sail ps

--with=mysql のみで構築した場合、以下のように表示されればOK:

0.0.0.0:81->80/tcp
0.0.0.0:3307->3306/tcp
  • Laravel側は http://localhost:81 でアクセスする
  • MySQLはホスト側 3307 からコンテナ側 3306 に転送される

phpMyAdminは --with=mysql だけでは起動しない。phpMyAdminサービスを追加している場合のみ、0.0.0.0:8082->80/tcp のような行が追加で表示される。


5. マイグレーション(初回のみ)

MySQLコンテナが起動してから実行する。
./vendor/bin/sail ps でSTATUSが healthy またはUpになっていればOK)

./vendor/bin/sail artisan migrate

以下のように表示されればOK:

INFO  Running migrations.
2014_10_12_000000_create_users_table ........... DONE
2014_10_12_100000_create_password_reset_tokens_table ... DONE
2019_08_19_000000_create_failed_jobs_table ..... DONE
2019_12_14_000001_create_personal_access_tokens_table .. DONE

6. Laravel Top画面表示

ブラウザで以下にアクセス:

http://localhost:81

Laravelのトップページが表示されれば成功。


7. バージョン確認

./vendor/bin/sail artisan --version
Laravel Framework 10.x.x

と表示されればOK。

PHPバージョン確認

Laravel本体のバージョンだけでなく、Sailコンテナ内のPHPバージョンも確認する。

./vendor/bin/sail php -v

PHP 8.2系になっていればOK。

PHP 8.2.x ...

注意:ここで確認しているのはWSL2ホスト側のPHPではなく、Laravel Sailコンテナ内のPHPである。ホスト側で php -v を実行した場合は、Ubuntu側にインストールされているPHPのバージョンが表示されるため、Sailで実際に使われるバージョンとは異なる場合がある。Laravel Sailコンテナ内のPHPを確認する場合は、必ず ./vendor/bin/sail php -v を使用すること。

意図しないバージョンになっている場合

もしPHP 8.5など、意図しないバージョンが表示された場合は、compose.yamllaravel.test サービスで使用しているruntimeを確認する。

grep -n "runtimes\|image:" compose.yaml

build.contextimage の両方がPHP 8.2を指しているか確認する。以下が正しい設定である:

build:
  context: './vendor/laravel/sail/runtimes/8.2'
  dockerfile: Dockerfile
image: 'sail-8.2/app'

以下のような不整合になっている場合は注意が必要である:

build:
  context: './vendor/laravel/sail/runtimes/8.5'
  dockerfile: Dockerfile
image: 'sail-8.2/app'

この状態では、image 名は sail-8.2/app でも、実際にはPHP 8.5のruntimeを元にビルドしている。実際に使われるPHP runtimeは build.context の指定で決まるため、runtimes/8.2sail-8.2/app の両方を揃える必要がある。

修正後は、既存コンテナとイメージを作り直す:

./vendor/bin/sail down
docker compose build --no-cache
./vendor/bin/sail up -d
./vendor/bin/sail php -v

PHP 8.2系になっていれば完了。


8. Laravel Sailを停止

./vendor/bin/sail down

停止・削除されるもの

  • コンテナ
  • ネットワーク

保持されるもの

  • ボリューム(MySQLデータ)

次回 ./vendor/bin/sail up -d で再起動してもデータは残る。


9. 通常の起動手順(2回目以降)

cd ~/projects/laravel10-project
./vendor/bin/sail up -d

./vendor/bin/sail artisan migrate は初回のみ必要。

補足:Sailコマンドのエイリアス設定

毎回 ./vendor/bin/sail と入力するのが手間な場合は、エイリアスを設定することで sail コマンドとして実行できる。

echo "alias sail='./vendor/bin/sail'" >> ~/.bashrc
source ~/.bashrc

これにより、以下のように簡略化できる:

sail up -d
sail down
sail artisan migrate

注意:このエイリアスはLaravelプロジェクトのディレクトリ内でのみ有効。


10. トラブルシューティング

Connection refusedエラーが出る場合

SQLSTATE[HY000] [2002] Connection refused

MySQLコンテナがまだ起動中のため。しばらく待ってから再実行する。

./vendor/bin/sail ps  # STATUSがhealthyまたはUpになるまで待つ
./vendor/bin/sail artisan migrate

Docker permission deniedが出る場合

Docker Desktopが起動しているか確認する。WSLからDockerが使用できない場合はDocker DesktopのWSL Integrationを有効にする。

Docker Desktop → Settings → Resources → WSL Integration

ポートが反映されない場合

.env にポート設定が追加されているか確認する:

grep -E "APP_PORT|FORWARD_DB_PORT|PHPMYADMIN_PORT" .env

表示されない場合は手動で追加してコンテナを再起動する:

echo 'APP_PORT=81' >> .env
echo 'FORWARD_DB_PORT=3307' >> .env
echo 'PHPMYADMIN_PORT=8082' >> .env
./vendor/bin/sail down
./vendor/bin/sail up -d

docker compose build --no-cache で WWWUSER / WWWGROUP の警告が出る場合

以下のような警告やエラーが出る場合がある:

WARN[0000] The "WWWUSER" variable is not set. Defaulting to a blank string.
WARN[0000] The "WWWGROUP" variable is not set. Defaulting to a blank string.
groupadd: invalid group ID 'sail'

原因.envWWWUSER / WWWGROUP が設定されていないため、SailのDockerfile内の $WWWGROUP が空のまま解釈され、ビルドが失敗する。

対処.env に追記してから再ビルドする:

echo "WWWUSER=$(id -u)" >> .env
echo "WWWGROUP=$(id -g)" >> .env
grep -n "WWWUSER\|WWWGROUP" .env
docker compose build --no-cache

一時的に環境変数を渡して実行する方法もある:

WWWUSER=$(id -u) WWWGROUP=$(id -g) docker compose build --no-cache

ただし、この方法は一時的な対処であるため、.env への追記を推奨する。

PHP 8.2にしたいのにPHP 8.5でビルドされる場合

compose.yaml のruntimeを確認する:

grep -n "runtimes\|image:" compose.yaml

image: sail-8.2/app だけではPHP 8.2になるとは限らない。実際に使われるPHP runtimeは build.context の指定で決まる。build.contextruntimes/8.5 になっていないか確認すること。

PHP 8.2で統一する場合は以下に揃える:

build:
  context: './vendor/laravel/sail/runtimes/8.2'
  dockerfile: Dockerfile
image: 'sail-8.2/app'

修正後は再ビルドする:

./vendor/bin/sail down
docker compose build --no-cache
./vendor/bin/sail up -d
./vendor/bin/sail php -v

PHP 8.2系が表示されれば完了。


11. まとめ

Laravel Sail環境は curl -s https://laravel.build/... | bash で簡単に作成できるが、Laravelのバージョンを固定できない点には注意が必要である。特定のLaravelバージョンを使用する場合は composer create-project laravel/laravel:^10.0 をDockerコンテナ内で実行する方法が最も確実で再現性が高い。

また、環境構築時には以下の点を押さえておくと、つまずきを減らせる:

  • -u "$(id -u):$(id -g)" はファイル所有者対策であり、Sailビルド時の WWWUSER / WWWGROUP とは別の指定である
  • WWWUSER / WWWGROUP はSailのDockerfileビルド時に参照される環境変数であり、.env への手動追記が必要である
  • PHP 8.2で構築したい場合は、compose.yamlbuild.contextruntimes/8.2)と imagesail-8.2/app)を揃えること
  • ポート設定は ./vendor/bin/sail ps で確認し、0.0.0.0:81->80/tcp0.0.0.0:3307->3306/tcp が表示されれば反映済みである
  • 既存LAMP環境と共存する場合はポートの衝突に注意すること

今回つまずいたポイント

今回つまずいた原因は、新規Laravelプロジェクト作成後に .env へ環境固有の設定を追加していなかったことです。

composer create-projectphp artisan sail:install --with=mysql では、LaravelプロジェクトやSail構成は作成されますが、既存LAMP環境と共存するための APP_PORT / FORWARD_DB_PORT や、Sailビルド時に使用する WWWUSER / WWWGROUP は自動では設定されません。

そのため、プロジェクト作成後に .env へ以下を追加する必要があります。

echo 'APP_PORT=81' >> .env
echo 'FORWARD_DB_PORT=3307' >> .env
echo "WWWUSER=$(id -u)" >> .env
echo "WWWGROUP=$(id -g)" >> .env

phpMyAdminを後から追加する場合は、必要に応じて以下も追加します。

echo 'PHPMYADMIN_PORT=8082' >> .env

12. Mailpitを追加する

Mailpitは、ローカル開発環境から送信されたメールを外部へ実送信せずに受け取り、ブラウザで内容を確認するための開発用メールツールである。

このプロジェクトは作成時に sail:install --with=mysql を実行しているため、Mailpitがまだ compose.yaml に含まれていない場合は、Sailの追加サービス機能を使用して追加する。

12-1. Mailpitサービスを追加する

Laravel Sailを起動した状態で、プロジェクトディレクトリから以下を実行する。

cd ~/projects/laravel10-project
./vendor/bin/sail artisan sail:add

サービスの選択画面が表示されたら、mailpit を選択する。

追加後、compose.yaml にMailpitサービスが含まれていることを確認する。

grep -n "mailpit" compose.yaml

12-2. Mailpit用の環境変数を確認する

.env のメール設定を確認する。

grep -E "^MAIL_|^FORWARD_MAILPIT" .env

以下の設定になっていることを確認する。

MAIL_MAILER=smtp
MAIL_HOST=mailpit
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

設定が存在しない場合、または異なる場合は .env を編集する。

MAIL_HOST=mailpitMAIL_PORT=1025 は、LaravelコンテナからMailpitコンテナへ接続するための内部接続設定である。ブラウザで開くMailpit管理画面のポートとは別なので、管理画面のポートを変更しても MAIL_PORT1025 のままにする。

12-3. 既存環境とポートが重複する場合

Mailpitは標準で次のホスト側ポートを使用する。

  • SMTP受信用:1025
  • 管理画面:8025

既存環境と重複する場合は、.env に別のホスト側ポートを追加する。

echo 'FORWARD_MAILPIT_PORT=1026' >> .env
echo 'FORWARD_MAILPIT_DASHBOARD_PORT=8026' >> .env

この設定を使用する場合でも、Laravel側のメール送信先は次のままにする。

MAIL_HOST=mailpit
MAIL_PORT=1025

12-4. Sailを再起動する

./vendor/bin/sail down
./vendor/bin/sail up -d

起動状態を確認する。

./vendor/bin/sail ps

標準ポートを使用している場合は、Mailpitに次のポート割り当てが表示される。

0.0.0.0:1025->1025/tcp
0.0.0.0:8025->8025/tcp

ポートを変更した場合は、次のように表示される。

0.0.0.0:1026->1025/tcp
0.0.0.0:8026->8025/tcp

12-5. Mailpit管理画面を開く

標準ポートの場合:

http://localhost:8025

ポートを 8026 に変更した場合:

http://localhost:8026

Laravelアプリからメールを送信し、Mailpitの管理画面にメールが表示されれば追加完了である。

Mailpitはローカル開発用であり、本番環境のメール送信には使用しない。

補足:インストール途中で Composer が異常終了した場合

今回の検証では、composer create-project の終盤で次のエラーが発生しました。

Generating optimized autoload files
Segmentation fault (core dumped)

この状態では、Laravelプロジェクトのディレクトリやvendorディレクトリが作成されていても、インストール処理が最後まで完了していない場合があります。

今回確認できた未完了の状態は、次のとおりです。

  • vendor/autoload.phpが生成されていない
  • php artisanを実行できない
  • sail:installが実行されていない
  • compose.yamlが生成されていない
  • .envAPP_KEYが空
  • 初期マイグレーションが未実行

なお、今回のログから確定できたのは、Composer実行中のPHPプロセスがSegmentation faultで異常終了したことまでです。
Docker Desktop、WSL、メモリ、コンテナイメージなど、直接的な原因までは特定できていません。

1. vendor/autoload.phpを確認する

プロジェクトディレクトリへ移動して確認します。

cd laravel10-project
ls -l vendor/autoload.php

次のようなエラーになる場合は、Composerのオートローダー生成が完了していません。

ls: cannot access 'vendor/autoload.php': No such file or directory

2. Composerのインストール処理を再実行する

プロジェクト直下で、composer installを単独で実行します。

docker run --rm \
  -u "$(id -u):$(id -g)" \
  -e COMPOSER_HOME=/tmp/composer \
  -v "$(pwd)":/opt \
  -w /opt \
  laravelsail/php82-composer:latest \
  composer install

composer.lockが存在する場合は、記録済みの依存関係を使用してvendorディレクトリを再構築します。

正常終了後、もう一度確認します。

ls -l vendor/autoload.php

3. Laravelが起動できることを確認する

docker run --rm \
  -u "$(id -u):$(id -g)" \
  -e COMPOSER_HOME=/tmp/composer \
  -v "$(pwd)":/opt \
  -w /opt \
  laravelsail/php82-composer:latest \
  php artisan --version

Laravelのバージョンが表示されれば、artisanを実行できる状態です。

4. Sail構成を生成する

compose.yamlまたはdocker-compose.ymlが存在しない場合は、Sail構成を生成します。

docker run --rm \
  -u "$(id -u):$(id -g)" \
  -e COMPOSER_HOME=/tmp/composer \
  -v "$(pwd)":/opt \
  -w /opt \
  laravelsail/php82-composer:latest \
  php artisan sail:install --with=mysql

生成を確認します。

ls -la

5. Sailを起動する

./vendor/bin/sail up -d

6. APP_KEYを確認する

grep '^APP_KEY=' .env

APP_KEY=のまま空の場合は、次を実行します。

./vendor/bin/sail artisan key:generate

7. 初期マイグレーションを実行する

Laravelの初期設定によっては、セッションやキャッシュの保存先としてデータベースを使用します。

./vendor/bin/sail artisan migrate

マイグレーション未実行の状態では、次のようなエラーが発生する場合があります。

SQLSTATE[42S02]: Base table or view not found
Table 'laravel.sessions' doesn't exist

再構築時の注意

同じプロジェクト名で作り直す場合、古いMySQLボリュームが残っていると、以前のデータベースが再利用される可能性があります。

ボリュームを確認します。

docker volume ls

対象プロジェクトを完全に初期化する場合は、ディレクトリ削除前に次を実行します。

./vendor/bin/sail down -v

すでにプロジェクトディレクトリを削除した場合は、対象ボリューム名を確認して個別に削除します。

docker volume rm laravel10-project_sail-mysql

ほかのプロジェクトのボリュームを誤って削除しないように注意してください。

今回発生したComposerのSegmentation faultは、MySQLボリュームを使用する前の処理で発生しました。
そのため、古いMySQLボリュームがSegmentation faultの直接原因だったとは判断できません。

※2026/07/11更新:目次リンクの修正と、Laravel Sail環境へMailpitを追加する手順を追記しました。
※2026/07/14更新:Laravel 10のインストール手順を見直し、Composer実行時の注意点とトラブル対応を追記しました。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?