Laravel SailでLaravelの開発環境を作ってみた

# 実施条件

Laravel 8.x ^
comporser 2.x ^
macOS BigSur
bash
Dockerは事前に入れていて、立ち上げている状態でいること

やり方が書いてるところ：[Laravel公式ドキュメント](https://readouble.com/laravel/8.x/ja/sail.html)

Laravel 8から公式がゴリ押ししているLaravel Sailを使ってみて、Laradocと何が違うのか体験してみたいと思います。

# プロジェクトファイルをどこでもいいので作る
自分が使いやすいと思われるディレクトリにプロジェクトファイルを作る。
(私はいつも書類フォルダの中に作っています。)

フォルダができたら、ターミナルでcdで移動しておく。

```
$ cd Documents
$ mkdir プロジェクトフォルダ名
$ cd プロジェクトフォルダ名
```

さっき作ったフォルダの中に、アプリを作るフォルダを作っていく。
なんで2階層作るのかわからないが、みんなそうやっているので深く考えず、やっておく。(フォルダの整理術なのか…？)

```
$ curl -s https://laravel.build/アプリフォルダ名 | bash
```

結構時間がかかる。。
終わったら、さっき作ったアプリフォルダ名(アプリケーションルートと言います)へcdしてから.envファイルを開く。

```
$ cd アプリフォルダ名
$ vi .env
```

開いたら、iキーを押してでインサートモードにして、どこでもいいのでわかりやすいところへ以下を追加。

```
APP_PORT=8090
FORWARD_DB_PORT=13306
FORWARD_REDIS_PORT=16379
```

ここのポート番号(=以降の数字の部分)はなんでもいいです。
ただ、10080はChromeとFirefoxがブロックするようになったみたいなので、推奨しているブログ記事がちらほらありましたが、それ以外の数字を使った方がいいみたいです。

参考：[😇Web Application開発に10080番ポートは使ってはいけない](https://zenn.dev/ota42y/articles/127fee3353bafe)

`esc`キーを押した後、`：wq!`とキーを順番に打っていって上書き保存してエディタを閉じる。
ポート番号が被って、sail upコマンドが失敗しないように、ここであらかじめ対策しておく。

アプリフォルダ名(アプリケーションルートと言います)にいる　状態で、以下のコマンドを実行して、vendor/bin/sailスクリプトを起動する。

```
$ ./vendor/bin/sail up
```

これで初回なので時間がかかると思いますが、以下のように全ての項目がdoneになっていれば成功。
うまくいかないとfailの赤文字が出て、文字の出力が止まるはず。

```
Creating network "example-app_sail" with driver "bridge"
Creating example-app_meilisearch_1 ... done
Creating example-app_mailhog_1     ... done
Creating example-app_selenium_1    ... done
Creating example-app_mysql_1       ... done
Creating example-app_redis_1       ... done
Creating example-app_laravel.test_1 ... done
```

これで、環境構築は完了です。

# sailコマンドを短く打つために.bashrcを編集
sailコマンドは、普段使っている`php artisan ~`を、`./vendor/bin/sail artisan`に変更して使います。

でも、毎回`./vendor/bin/sail`と、打つのは面倒ですよね。
そこで、もっと短くsailコマンドを打つために.bashrcを作って編集します。

.bashrcを作ってエイリアスを作ります。以下のコマンドを入力します。

```
$ vi ~/.bashrc
```

.bashrcがvimで開くので、またまたiキーを押してインサートモードにして、どこでもいいのでわかりやすいところへ以下を追加。
(初めて.bashrcを作る人は何にも書いてないはず)

```
alias sail='[ -f sail ] && bash sail || bash vendor/bin/sail'
```

`esc`キーを押した後、`：wq!`とキーを順番に打っていって上書き保存してエディタを閉じる。

初めて.bashrcを作った場合、.bash_profileに.bashrcを読み込むように記述がされていないので、以下のコマンドで.bash_profileを開きます。

```
$ vi ~/.bash_profile
```

開けたら、iキーでインサートモードにして以下を追加します。

```
if [ -f ~/.bashrc ] ; then
. ~/.bashrc
fi
```

`esc`キーを押した後、`：wq!`とキーを順番に打っていって上書き保存してエディタを閉じる。

これで、ターミナルを一回閉じて立ち上げなおすと短いsailコマンドが使える準備が整いました。

## sailコマンドを使ってみる
早速使ってみましょう。
開発を始めるときは、必ずdocker desktopは起動した状態であることを確認してから以下のことを行なってください。

cdでさっきのプロジェクトファイル名2に移動して、sailコマンドを打つ。
(ややこしいですが、一番最初に作ったプロジェクトフォルダではないです。その中にさらに作ったプロジェクトフォルダです。アプリケーションルートと言います)

```
$ cd Documents/プロジェクトフォルダ名/プロジェクトファイル名2
$ sail up -d
```

`$ sail up`だと動かしている間ずっとだらだらと文字が出力され続けますが、-dをつけるだけで裏で動いてくれます。
(dはデーモンのd。裏でやってくれることをデーモンと言うらしいです。)

開発が終わって、コンテナを止めるときは以下のコマンドで。

```
$ sail down
```

# ブラウザで確認してみる
さてさて、いよいよローカルのlaravelアプリケーションの初期画面を開いてみましょう。
ブラウザで以下を開くだけです。

[http://localhost:8090](http://localhost:8090)

この、`:`以降の数字は.envファイルに入れた`APP_PORT=8090`の数字と同じにしてください。


## php artisanコマンドを打ちたいとき
phpだったところをsailに置き換えるだけです。

正） `sail artisan なんかコマンド`
誤) `php artisan` なんかコマンド

MAMPに比べるとコンテナを解すからかワンテンポ遅いですが、ちゃんと動きます。


# Dockerfileを編集して日本時間にしたりする

アプリケーションルートへ移動してから、以下のコマンドでdockerディレクトリを作る。

```
$ cd Documents/プロジェクトフォルダ名/プロジェクトファイル名2
$ sail artisan sail:publish
```

以下のメッセージ通り、アプリケーションルート直下にdockerというフォルダができているはず。
```
Copied Directory [/vendor/laravel/sail/runtimes] To [/docker]
Publishing complete.
```

dockerフォルダの中には3つフォルダがあると思いますが、どれを開いたらいいのか調べましょう。

もともとアプリケーションルート直下に存在していた`docker-compose.yml`を開くと6行目あたりに以下の記述があって、/8.1が使われていることがわかります。

```
build:
  context: ./docker/8.1
  dockerfile: Dockerfile
```

というわけで、dockerフォルダの中にある/8.1/Dockerfileをテキストエディタか、viで開いてください。
12行目あたりに`ENV TZ=UTC`と、環境のタイムゾーンがUTC(標準時間)になっているのでここを日本時間に変えます。

```
ENV TZ='Asia/Tokyo'
```

保存できたら、ターミナルでサイビルドさせます。

```
$ sail build --no-chache
```

1分ぐらい時間がかかります。

# アプリケーションの設定を日本時間にして日本語設定にする
アプリの設定ファイルはアプリケーションルートのconfig/app.phpの72行目あたりにあるので以下のように変えます。

```
    'timezone' => 'Asia/Tokyo',
```

言語設定は82行目あたりにあります。

```
'locale' => 'ja',
```

# MySQLの文字コード変更(文字化け対策)
先ほど触ったDocker/8.1の中に設定ファイルmy.cnfを新規作成して以下を記述します。

```
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_bin

[client]
default-character-set = utf8mb4
```

今度は`docker-compose.yml`を開いて、40行目あたりにあるvolumesに
`- './docker/8.1/mycnf:/etc/mycnf'`の記述を追加しましょう。

```
volumes:
     - 'sail-mysql:/var/lib/mysql'
      - './docker/8.1/my.cnf:/etc/my.cnf'
```

`sail down`でコンテナを停止させてからまた`sail up -d`で再起動させてから以下のコマンドで文字コードを確認してください。

```
$ sail mysql

mysql> show variables like '%char%';
```

すると以下の出力結果が得られて、文字コードが変更できたことがわかります。
```
+--------------------------+--------------------------------+
| Variable_name            | Value                          |
+--------------------------+--------------------------------+
| character_set_client     | utf8mb4                        |
| character_set_connection | utf8mb4                        |
| character_set_database   | utf8mb4                        |
| character_set_filesystem | binary                         |
| character_set_results    | utf8mb4                        |
| character_set_server     | utf8mb4                        |
| character_set_system     | utf8mb3                        |
| character_sets_dir       | /usr/share/mysql-8.0/charsets/ |
+--------------------------+--------------------------------+
8 rows in set (0.01 sec)

```

# Laravel Sailのメリット
## データベースの設定は勝手にやってくれる
MAMPだと、データベースを作って、`.env`ファイルを作ったデータベースに合わせて書き換えないと接続できないというデメリットがあった。
でもLaravel sailを使うとそこのところは勝手にやってくれている。

## テスト環境やmailhog, redisなどはすでに入ってる
テストに使うseleniumや、ローカル開発環境での電子メールのテストに使うmailhog,データベース管理システムのredisなどが環境を立ち上げた際にすでに入れておいてくれます。
便利。