【Docker】Laravel Sailのインストールと使い方を確認

Laravel 9に対応した内容に更新しています。
macOSを利用してLaravelの開発を行う場合は、ローカルのmacOSにPHP、 node、composer、MySQLなどLaravelのインストールや動作に必要なアプリケーションを事前にインストールしておく必要があります。Dockerを利用する場合、Laravel SailではローカルのmacOSとは別に独立環境をDocker上に構築するためローカルのmacOS上に個別にアプリケーションをインストールすることなくLaravelの開発環境を構築することができます。
Dockerは少し敷居が高く感じられDockerがわからないからDockerを利用しない方法で開発環境を構築するとLaravel Sailを敬遠しないで下さい。Laravel SailではDockerを利用するためDockerのインストールが必須となりますがDockerの知識がなくても利用可能です。Laravelプロジェクトの開発環境を構築する方法は複数存在しますがLaravel 9のドキュメントではLaravelプロジェクトを作成する方法としてLaravel Sailを利用した方法が最初に記載されています。

Dockerの知識が本当に必要ないのかも含めてLaravel Sailを使ってLaravelの開発環境を構築していきましょう。

目次
Dockerのインストール
Laravel Sailを利用するためにはDockerのインストールが必要となります。macOSであればHomebrewからもインストールすることが可能ですが、ここではDocker公式のホームページからインストールを行います。

”Get Stared”ボタンをクリックするとダウンロード画面が表示されます。左側のDocker Desktopの”Download for Mac”をクリックとダウンロードが開始されます。

Docker.dmgファイルのダウンロードが完了したらダブルクリックを行います。
下記の画面が表示されるので左側のDockerをApplicationsフォルダにドラッグ&ドロップしてください。

メニューの移動からアプリケーションを選択するとDockerがインストールされていると思うのでDockerをダブルクリックで起動してください。ファイルを開くための確認画面が表示されるので”開く”をクリックしてください。

Docker Desktopを起動するための権限が必要となるためパスワードを入力する必要があります。そのまま”OK”ボタンをクリックしてください。

パスワード入力画面が表示されるのでパスワードを入力してください。Dockerの起動が開始されます。

サービスアグリーメントの画面が表示されるので内容に問題がない場合は”I accept the terms”にチェックを行い”Accept"ボタンをクリックしてください。Dockerの起動が開始されます。

Docker Desktopが起動してインストールを行った週のTipsが表示されます。インストールを行う日によって内容は変わります。

Docker Desktopのダッシュボード管理画面が表示されます。

Laravelのインストール
Dockerの起動が完了したらDockerへのLaravelのインストールを行います。Laravelへアクセスできる状態にするまでにたった2つのコマンドで完了します。
下記のcurlコマンドを実行することでDockerにLaravelをインストールすることができます。example-appの部分は任意の名前に変更することが可能です。ここで設定した名前がプロジェクト名となります。
% curl -s https://laravel.build/example-app | bash
bashのスクリプトですが、https://laravel.build/example-appの中身も確認しておきましょう。Laravelのドキュメントではexample-appになっていますがプロジェクト名をlaravel-sail-appに変更してhttps://laravel.build/laravel-sail-appにブラウザから直接アクセスするとスクリプトの中身を確認することができます。
docker info > /dev/null 2>&1
# Ensure that Docker is running...
if [ $? -ne 0 ]; then
echo "Docker is not running."
exit 1
fi
docker run --rm \
-v "$(pwd)":/opt \
-w /opt \
laravelsail/php81-composer:latest \
bash -c "laravel new laravel-sail-app && cd laravel-sail-app && php ./artisan sail:install --with=mysql,redis,meilisearch,mailhog,selenium "
cd example-app
CYAN='\033[0;36m'
LIGHT_CYAN='\033[1;36m'
WHITE='\033[1;37m'
NC='\033[0m'
echo ""
if sudo -n true 2>/dev/null; then
sudo chown -R $USER: .
echo -e "${WHITE}Get started with:${NC} cd laravel-sail-app && ./vendor/bin/sail up"
else
echo -e "${WHITE}Please provide your password so we can make some final adjustments to your application's permissions.${NC}"
echo ""
sudo chown -R $USER: .
echo ""
echo -e "${WHITE}Thank you! We hope you build something incredible. Dive in with:${NC} cd example-app && ./vendor/bin/sail up"
fi
スクリプトの中では、Laravelをインストールを行う際に利用するlaravel newコマンドも確認することができます。
bashスクリプトの内容も確認したのでLaravelのインストールを行います。実行すると実行したフォルダの下にlaravel-sail-appのフォルダが作成されます。
% curl -s https://laravel.build/laravel-sail-app | bash
インストールの途中に下記のメッセージが表示されますが、”OK”ボタンをクリックしてください。

最後にパスワードの入力を求められるのでパスワードを入力してください。パスワードの入力が完了するとlaravel-sail-appフォルダに移動してsail upコマンドを実行してください。
//略
Package manifest generated successfully.
78 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan vendor:publish --tag=laravel-assets --ansi --force
No publishable resources for tag [laravel-assets].
Publishing complete.
> @php artisan key:generate --ansi
Application key set successfully.
Application ready! Build something amazing.
Sail scaffolding installed successfully.
Please provide your password so we can make some final adjustments to your application's permissions.
Password:
Thank you! We hope you build something incredible. Dive in with: cd laravel-sail-app && ./vendor/bin/sail up

sail upコマンドを初めて実行するとDockerのコンテナの作成が行われるのでしばらく完了までに時間がかかります。最初の1回目のみなので2回目からはそれほど時間はかかりません。
% cd laravel-sail-app && ./vendor/bin/sail up
他のサービスがDockerのLaravelで利用するポートを使用している場合はエラーが発生します。
Creating laravel-sail-app_mailhog_1 ... done
Creating laravel-sail-app_mysql_1 ... done
Creating laravel-sail-app_redis_1 ... done
Creating laravel-sail-app_laravel.test_1 ... error
ERROR: for laravel-sail-app_laravel.test_1 Cannot start service laravel.test: Ports are not available: listen tcp 0.0.0.0:80: bind: address already in use
ERROR: for laravel.test Cannot start service laravel.test: Ports are not available: listen tcp 0.0.0.0:80: bind: address already in use
エラー内容により本環境ではポートの80がすでに使用されていることがわかります。本環境ではLavaelのValetもインストール済なのでnginxがポート80で起動しているためvaletを停止します。
% valet stop
Password:
Stopping php...
Stopping nginx...
Valet services have been stopped.
nginxを停止後に再度sail upコマンドを実行します。
% ./vendor/bin/sail up
今度はエラーが発生したかったのでブラウザでlocalhostにアクセスします。Laravelのトップページが表示されればLaravel Sailのインストールは正常に完了しています。

Laravelへアクセスできる状態にするまでに下記の2つのコマンドのみだったことが確認できました。
% curl -s https://laravel.build/laravel-sail-app | bash
% cd laravel-sail-app && ./vendor/bin/sail up
Laravel SailでLaravelのインストールを行うとデフォルトではmysql, mailhog, meilisearch, redis, seleniumのサービスが設定されます。下記のようにwithを利用することで設定するサービスを選択することができます。https://laravel.build/example-appのスクリプトを見るとwithでサービスが指定されていることが確認できます。
% curl -s "https://laravel.build/example-app?with=mysql,redis" | bash
設定できるサービスにはmysql, pgsql, mariadb, redis, memcached, meilisearch, minio, seleniumがあります。
Dockerのダッシュボードを確認するとインストールしたコンテナを確認することができます。

Laravelの動作確認
Docker上のLaravelにアクセスすることはできました。データベース上にテーブルを作成したい場合、新規のモデル、コントローラーを作成したい場合にローカルにLaravelをインストールしたようにphp artisanコマンドを実行することができるのでしょうか?
Laravel Sailではphp artisanコマンドを実行したい場合はsailコマンドをつけて行います。下記のようにphp –versionによってもphpのバージョンを確認することができますがphpで実行した場合はローカルのPCのPHPが利用されていることがわかります。sailコマンドを利用して実行した場合はDockerコンテナにインストールされているPHPが利用されることになります。
% php --version
PHP 8.0.7 (cli) (built: Jun 4 2021 03:56:55) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.7, Copyright (c) Zend Technologies
with Zend OPcache v8.0.7, Copyright (c), by Zend Technologies
% sail php --version
PHP 8.1.2 (cli) (built: Jan 24 2022 10:42:51) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.2, Copyright (c) Zend Technologies
with Zend OPcache v8.1.2, Copyright (c), by Zend Technologies
with Xdebug v3.1.2, Copyright (c) 2002-2021, by Derick Rethans
Laravelのバージョンを確認したい場合はsail artisan -Vコマンドで確認できます。
% sail artisan -V
Laravel Framework 9.0.0
テーブルの作成
sailコマンドを利用してDocker上のLaravel環境でテーブルの作成を行います。下記のようにコマンドを実行することでテーブルを作成することができます。
% ./vendor/bin/sail artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (44.86ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table (31.08ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated: 2019_08_19_000000_create_failed_jobs_table (27.66ms)
Migrating: 2019_12_14_000001_create_personal_access_tokens_table
Migrated: 2019_12_14_000001_create_personal_access_tokens_table (42.33ms

通常だとMySQLなどのデータベースの作成などを事前に実行しておく必要がありますが、Laravel SailではMySQLの設定(sail upコマンドでMySQLコンテナを作成)も完了しているのでMySQLに関する設定を何も行う必要がありません。
Laravelの.envファイルを確認するとデータベースの接続情報を確認することができます。
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel_sail_app
DB_USERNAME=sail
DB_PASSWORD=password
データベースに接続したい場合はLaravelの公式ドキュメントに記載されているようにデータベースのGUI管理ソフトのTablePlusによって接続することも可能です。

TablePlusを起動し、右側の”No connection…”で右クリックをして表示されるメニューから”New”→”Connection”を実行します。

データベース選択画面が表示されるので、MySQLを選択してください。

TablePlus上で識別するための任意の名前をつけます。名前をつけたら右下部の”connect”をクリックします。Port等にデフォルトの3306が設定されていますが変更は必要ありません。先ほど確認した.envファイルに記載しているPORT番号を利用します。

データベースのバージョンやポート番号についてはLaravelのプロジェクトフォルダのdocker-compose.ymlに記載されています。
mysql:
image: 'mysql:8.0'
ports:
- '${FORWARD_DB_PORT:-3306}:3306'
TablePlusの”Connect”ボタンをクリックする下記の画面が表示されるので上部右側にあるディスクアイコンをクリックしてください。

データベースの選択画面が表示されるので、laravel_sail_appを選択してください。データベースの名前も.envファイルに記載されています。

laravel_sail_appにアクセスすると先ほどsail artisan migrateコマンドの実行で作成したテーブルを確認することができます。

Laravelのコンテナ上でコマンドを実行
sailコマンドでphp artisanコマンドを実行することが確認できました。sailコマンドではなくLaravelの入ったコンテナ上でコマンドを実行したい場合はsail shellでコンテナに接続することができます。
接続できればローカルOSのようにコマンドを実行することができます。
% ./vendor/bin/sail shell
sail@3b0b40fbc796:/var/www/html$ php artisan --version
Laravel Framework 9.0.0

接続を終了したい場合はexitコマンドを実行してください。
sail@767905ffad13:/var/www/html$ exit
exit
認証パッケージBreezeのインストール
Laravelのコンテナに接続することができたのでLaravel Sailでも問題なく認証パッケージであるBreezeが動作するのか確認します。Breezeパッケージはcomposerコマンドを利用してインストールします。sail shellでLaravelコンテナに接続しています。
sail@767905ffad13:/var/www/html$ composer require laravel/breeze --dev
sail shellを利用せずsailコマンドを利用することもできます。
% ./vendor/bin/sail composer require laravel/breeze --dev
インストール後php artisan breeze:installコマンドを実行します。
sail@767905ffad13:/var/www/html$ php artisan breeze:install
Breeze scaffolding installed successfully.
Please execute the "npm install && npm run dev" command to build your assets.
sail shellを利用せずsailコマンドを利用することもできます。
% ./vendor/bin/sail artisan breeze:install
メッセージに従ってnpmコマンドを実行し、JavaScriptライブライのインストールとビルドを行います。
sail@767905ffad13:/var/www/html$ npm install && npm run dev
sail shellを利用せずsailコマンドを利用することもできます。
% ./vendor/bin/sail npm install && npm run dev
メッセージに従ってnpmコマンドを実行し、JavaScriptライブライのインストールとビルドを行います。
ビルドが完了するとLaravelトップページの右上にLogin Registerのリンクが表示されます。

Registerのリンクをクリックして、ユーザの登録を行います。

ユーザ登録後にTablePlusでデータベースにアクセスしユーザが追加されていることを確認します。

通常の開発環境と同様にLaravel Sailを利用しても問題なく認証機能の追加、データベースへのユーザの登録ができることが確認できました。
パスの設定
Docker上のコンテナを操作するためsailコマンドを実行してきましたが、sailコマンドはvendor/binフォルダにあるため実行する際にvendor/bin/sailとパスを指定して実行する必要があります。入力する文字が長いのでalias(エイリアス)を登録してsailで実行できるように設定します。
macOS Big Sur(Catolinaも同様)のデフォルトのシェルはZSHなので.zshrcにaliasを追加します。.zshrcがない場合はユーザのホームディレクトリで.zshrcを作成してください。
alias sail="vendor/bin/sail"
設定を即座に反映させたい場合はsourceコマンドを実行してください。
% source .zshrc

Laravelプロジェクトのフォルダに移動してsailコマンドを実行するとvendor/binなしで実行することができます。本環境ではlaravel-sail-appフォルダの直下です。
sailコマンドを実行すると稼働しているDockerコンテナの状態を確認することができます。4つのコンテナがあり、laravel, mailhog, meilisearch, mysql, redis, seleniumが動作していることが確認できます。
% sail
NAME COMMAND SERVICE STATUS PORTS
laravel-sail-app-laravel.test-1 "start-container" laravel.test running 0.0.0.0:80->80/tcp
laravel-sail-app-mailhog-1 "MailHog" mailhog running 0.0.0.0:1025->1025/tcp, 0.0.0.0:8025->8025/tcp
laravel-sail-app-meilisearch-1 "tini -- /bin/sh -c …" meilisearch running (healthy) 0.0.0.0:7700->7700/tcp
laravel-sail-app-mysql-1 "/entrypoint.sh mysq…" mysql running (healthy) 0.0.0.0:3306->3306/tcp
laravel-sail-app-redis-1 "docker-entrypoint.s…" redis running (healthy) 0.0.0.0:6379->6379/tcp
laravel-sail-app-selenium-1 "/opt/bin/entry_poin…" selenium running 5900/tcp

sailコマンドの確認
sailコマンドはvendor/binフォルダの下に保存されているスクリプトファイルで内部ではDockerのコマンドが実行されています。スクリプトなのでファイルの中身を確認することができます。
sail up(コンテナの起動)
Dockerコンテナを起動する場合はsail upコマンドを実行します。sail upコマンドを実行することでコンテナが起動します。コンテナが起動するとブラウザからLaravelアプリケーションに接続することができます。
% sail up
バックグランドで起動させたい場合はsail upに-dオプションをつけて実行します。
% sail up -d
sail stop(コンテナの停止)
sail upで実行した場合はCtrl + Cで停止することができます。バックグランドで起動したコンテナを停止したい場合はsail stopコマンドを実行します。
% sail stop
Stopping laravel-sail-app_laravel.test_1 ... done
Stopping laravel-sail-app_mysql_1 ... done
Stopping laravel-sail-app_mailhog_1 ... done
Stopping laravel-sail-app_redis_1 ... done
sail ps(コンテナのリストを表示)
コンテナのリストを表示させたい場合はsail psコマンドを実行します。コンテナが停止している場合に実行してもコンテナの情報は表示されません。
% sail ps
Name Command State Ports
-------------------------------------------------------------------------------------------------------------------------
laravel-sail-app_laravel.test_1 start-container Up 0.0.0.0:80->80/tcp, 8000/tcp
laravel-sail-app_mailhog_1 MailHog Up 0.0.0.0:1025->1025/tcp, 0.0.0.0:8025->8025/tcp
laravel-sail-app_mysql_1 docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp, 33060/tcp
laravel-sail-app_redis_1 docker-entrypoint.sh redis ... Up 0.0.0.0:6379->6379/tcp
sail shell(コンテナに接続)
Laravelのコンテナに接続し、sailを介さずにコマンドを実行したい場合はsail shellコマンドを実行します。
% sail shell
sail@e69a1e342550:/var/www/html$
var/www/htmlに存在するファイルと作成したlaravel-sail-appのファイル一致します。
接続を終了する場合はexitコマンドを実行してください。
sail bashでも同様に接続することが可能です。
sail mysql(MySQLヘの接続)
MySQLに直接接続してSQLを実行したい場合はsail mysqlコマンドを利用することでMySQLに接続を行うことができます。
% sail mysql
パスワードの入力等もなしでそのまま接続できるので既存のテーブルとusersテーブルを確認します。
mysql> show tables;
+----------------------------+
| Tables_in_laravel_sail_app |
+----------------------------+
| failed_jobs |
| migrations |
| password_resets |
| personal_access_tokens |
| users |
+----------------------------+
5 rows in set (0.00 sec)
mysql> select * from users;
+----+----------+------------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
| id | name | email | email_verified_at | password | remember_token | created_at | updated_at |
+----+----------+------------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
| 1 | John Doe | john@example.com | NULL | $2y$10$4x99UZfRvZjoWnTP5cAii.YHiO9gSYXRrXJIQEdubMZQGffzV9EKC | NULL | 2021-01-13 04:39:21 | 2021-01-13 04:39:21 |
+----+----------+------------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
1 row in set (0.01 sec)
Dockerコマンドを使えるのか?
Laravel SailはDocker上で稼働しているためsailコマンドを利用なくてもdockerコマンドを実行することができます。
MySQLに接続したい場合は下記のDockerコマンドでも接続することができます。
% docker exec -it laravel-sail-app_mysql_1 mysql -u root -p
まとめ
Laravel Sailを利用する際にDockerの知識があったほうがよいことは疑う余地はありませんが、Dockerの知識がなくてもLaravelの開発が行えるということがわかってもらえたかと思います。ローカルのマシンにさまざななアプリケーションをインストールすることなく開発環境を短時間で構築できるのは非常に魅了ではないでしょうか。