macOSを利用してLaravelの開発を行う場合は、ローカルのmacOSにPHP、 node、composer、MySQLなどLaravelのインストールや動作に必要なアプリケーションを事前にインストールする必要があります。Dockerを利用するLaravel Sailでは、ローカルのmacOSとは別に独立環境をDocker上に構築するためローカルのmacOSに影響を与えることなくLaravelの開発環境を構築することができます。

Dockerとう名前を聞くと敷居が高いと思ってしまうかもしれません。Laravel SailではDockerを利用するためにインストールは必要となりますがDockerの知識がなくても利用できます。

Dockerの知識がなくてもLaravelを利用することが可能ですが、sailコマンドを頻繁に利用するためsailコマンドの使用方法は理解する必要があります。sailコマンドを実行するとdockerのコマンドが実行されています。

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

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

Dockerのインストール

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

Dockerのホームページ
Dockerのホームページ

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

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

Docker.dmgがダウンロードされるのでダウンロードが完了したらクリックを行ってください。

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

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

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

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

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

確認画面
確認画面

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

起動が終わるとチュートリアルの画面が起動しますが、Dockerの起動が完了しているので”Skip Tutorial”をクリックしても構いません。

チュートリアルの表示
チュートリアルの表示

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/php80-composer:latest \
    laravel new laravel-sail-app

cd laravel-sail-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 laravel-sail-app && ./vendor/bin/sail up"
fi

sed -i.backup 's/DB_HOST=127.0.0.1/DB_HOST=mysql/g' .env
sed -i.backup 's/DB_HOST=127.0.0.1/DB_HOST=mysql/g' .env.example
sed -i.backup 's/MEMCACHED_HOST=127.0.0.1/MEMCACHED_HOST=memcached/g' .env
sed -i.backup 's/MEMCACHED_HOST=127.0.0.1/MEMCACHED_HOST=memcached/g' .env.example
sed -i.backup 's/REDIS_HOST=127.0.0.1/REDIS_HOST=redis/g' .env
sed -i.backup 's/REDIS_HOST=127.0.0.1/REDIS_HOST=redis/g' .env.example

rm -f .env.backup
rm -f .env.example.backup

スクリプトの中では、Laravelをインストールを行う際に利用するlaravel newコマンドも確認することができます。

bashスクリプトの内容も確認したのでLaravelのインストールを行います。実行すると実行したフォルダの下にlaravel-sail-appのフォルダが作成されます。


% curl -s https://laravel.build/laravel-sail-app | bash

インストールの途中に下記のメッセージが表示されますが、”OK”ボタンをクリックしてください。

アクセスの確認メッセージ
アクセスの確認メッセージ

最後にパスワードの入力を求められるのでパスワードを入力してください。パスワードの入力が完了するとlaravel-sail-appフォルダに移動してsail upコマンドを実行してください。


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トップページ
Laravelトップページ

Laravelへアクセスできる状態にするまでに下記の2つのコマンドのみだったことが確認できました。


% curl -s https://laravel.build/laravel-sail-app | bash
% cd laravel-sail-app && ./vendor/bin/sail up

Laravelの動作確認

Docker上のLaravelにアクセスすることはできましたが、データベース上にテーブルを作成したい場合、新規のモデル、コントローラーを作成したい場合にこれまでのようにphp artisanコマンドを実行することができるのでしょうか?

Laravel Sailではphp artisanコマンドを実行したい場合はsailコマンドを利用して行います。

テーブルの作成

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 (60.87ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (37.93ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (36.00ms)
コマンドは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=root
DB_PASSWORD=

データベースに接続したい場合はLaravelの公式ドキュメントに記載されているようにデータベースのGUI管理ソフトのTablePlusによって接続することも可能です。

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

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

TablePlus起動
TablePlus起動

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

MySQLを選択
MySQLを選択

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

名前をつける
名前をつける

データベースのバージョンを8に設定していますが、データベースのバージョンやポート番号についてはLaravelのプロジェクトフォルダのdocker-compose.ymlに記載されています。


mysql:
    image: 'mysql:8.0'
    ports:
        - '${FORWARD_DB_PORT:-3306}:3306'

TablePlusの”Connect”ボタンをクリックすると上部にあるディスクアイコンをクリックしてください。

MySQLデーベースへの接続
MySQLデーベースへの接続

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

データベースの選択
データベースの選択

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

テーブルの確認
テーブルの確認

Laravelのコンテナ上でコマンドを実行

sailコマンドでphp artisanコマンドを実行することが確認できました。sailコマンドではなくLaravelの入ったコンテナ上でコマンドを実行したい場合はsail shellでコンテナに接続することができます。

接続できればローカルOSのようにコマンドを実行することができます。


 % ./vendor/bin/sail shell
sail@767905ffad13:/var/www/html$ php artisan --version
Laravel Framework 8.22.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

インストール後php artisan breeze:installコマンドを実行します。


 % php artisan breeze:install
Breeze scaffolding installed successfully.
Please execute the "npm install && npm run dev" command to build your assets.

メッセージに従ってnpmコマンドを実行し、JavaScriptライブライのインストールとビルドを行います。


$ npm install && npm run dev

ビルドが完了すると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, mysql, redisが動作していることが確認できます。


 % sail
             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   
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 down(コンテナの停止)

起動したコンテナを起動したい場合はsail downコマンドを実行します。


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