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コマンドを頻繁に利用するためsailコマンドの使用方法は理解する必要があります。sailコマンドを実行することで裏側ではdockerのコマンドが実行されます。

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

DockerをインストールすればmacOSだけではなくWindows、LinuxでもLaravel Sailを利用することができます。

Dockerのインストール

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

Dockerトップページ
Dockerトップページ

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

Docker Desktopダウンロード画面
Docker Desktopダウンロード画面

Docker.dmgファイルのダウンロードが完了したらダブルクリックを行います。

下記の画面が表示されるので左側のDockerをApplicationsフォルダにドラッグ&ドロップしてください。

Dockerのインストール
Dockerのインストール

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

ファイルを開くための確認
ファイルを開くための確認

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

確認画面
確認画面

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

OSのユーザパスワード入力画面
OSのユーザパスワード入力画面

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

サービスアグリーメント画面
サービスアグリーメント画面

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

Docker Desktop起動後の画面
Docker Desktop起動後の画面

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

Docker Desktopの管理画面
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
パスワード入力後にchmod(): Operation not permittedが発生しDesktopでlsコマンドが実行できなくなった場合はシステムの環境設定→セキュリティとプライバシー→フルディスクアクセスの画面で”変更するにはカギをクリックします”でパスワードを入力後ターミナルにチェックを行うと問題は解消されます。一度作成したlaravel-sail-appを削除してもう一度インストールを行うとエラーは表示されません。

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のインストールは正常に完了しています。

Laravel9初期ページ
Laravel9初期ページ

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
コマンドはLaravelのプロジェクトフォルダであるlarave-sail-appで行ってください。

通常だと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によって接続することも可能です。

MySQLデータベースに直接接続したい場合はsail mysqlコマンドで接続することが可能です。本文書でも後ほど説明しています。

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

TablePlus起動
TablePlus起動

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

MySQLを選択
MySQLを選択

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

MySQLヘの接続設定
MySQLヘの接続設定

データベースのバージョンやポート番号については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
ローカルOSのようにすべてのコマンドがあるわけではありません。

接続を終了したい場合は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
ターミナルを再度開いた場合は.zshrcの内容が読み込まれるためsourceコマンドは必要ありません。

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
mailhogという聞き慣れない名前のコンテナが表示されていますが、mailhogはメールの送受信テストに利用することができます。本ブログでも何度も登場しているMailtrapと同様の機能を持ったものです。

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の開発が行えるということがわかってもらえたかと思います。ローカルのマシンにさまざななアプリケーションをインストールすることなく開発環境を短時間で構築できるのは非常に魅了ではないでしょうか。