HomesteadでLaravel環境構築(Windows10)

#前置き
もう各所で散々書かれている内容だから私が書かなくても…と思ったのですが、

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">「すでにネット上に同じ情報があるのだからQiitaに書くべきでない」という主張を目にすることがあるが、僕は反対の立場を取る。<br><br>技術の再発明ならぬ「技術の再説明」が大事だと思うからだ。学んだことは気にせずどんどん書いていったほうがいいと思う。</p>&mdash; suin❄️PHPでオブジェクト指向 (@suin) <a href="https://twitter.com/suin/status/1112699973831782400?ref_src=twsrc%5Etfw">2019年4月1日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

というsuinさんのツイートに背中を押されたので書くことにしました。
七転八倒したポイントを重点的に書けばいいよね。うんうん。

#環境
※ 構築したのは2019年1月頃

* Windows10
* Oracle VM VirtualBox 6.0
* vagrant 2.2.2
* PHP 7.2
* Laravel 5.7.21

#準備
* [VirtualBox](https://www.virtualbox.org/) インストール
* [Vagrant](https://www.vagrantup.com/) インストール
 * 上記2つをインストールしたら一旦PCを再起動してください
* Git Bashがあると便利
 * [Git for Windows公式](https://gitforwindows.org/)

#BOX追加

Git Bashまたはコマンドプロンプトを起動して以下を入力

```bash:GitBash
cd c:\
vagrant box add laravel/homestead
```

ここで「Enter your choice:」と出るので、
3(virtualbox) を入力してEnterします。

しばらく待って、以下のような表示が出ればOK

```bash:GitBash
==> box: Successfully added box 'laravel/homestead' (v6.4.0) for 'virtualbox'!
```

#Homesteadダウンロード(git clone)

公式からcloneします。
ディレクトリ名はお好きに。今回は特に何も考えずHomesteadにしました。

```bash:GitBash
git clone https://github.com/laravel/homestead.git ~/Homestead
```

#設定の初期化

```bash:GitBash
cd ~/Homestead

./init.sh
# Homestead initialized! と表示されたらOK
```

#Homestead.yamlの修正

foldersとsitesを修正します

```bash:Gitbash
# 場所は ~/Homestead のまま
vi Homestead.yaml
```

```yaml:Homestead.yaml
# (中略)
folders:
    - map: D:\homestead\Laravel # ローカルディレクトリ
      to: /home/vagrant/code # vagrant上のディレクトリ

sites:
    - map: homestead.test # host名(起動後のドメイン名)
      to: /home/vagrant/code/public # web上に公開するディレクトリ(Apachで言うところのhtdocs)
```

##(補足) sites:mapに記載するドメイン名について

後で構築した環境をブラウザで確認するとき、
取り急ぎ `https://` ではなく `http://` でアクセスする場合は
homestead.app ではなく **homestead.test** を指定する方が無難です。

`http://homestead.app` は `https://homestead.app` とリダイレクトされるのですが、
Chromeだと自己署名証明書がエラーとなるためアクセスできないためです。

ただ、昨今の情勢としてはSSL通信で動かすことがベターだと思うので、
余裕があれば自己証明が通るよう設定した方がいいかもしれません。
(私はまだやってない……)

* [Chromeに怒られないオレオレ証明書の作り方](https://qiita.com/masahiro-aoike/items/dbf17fa03c5973ce9068)
* [Laravel Homestead 自己証明書でSSLを有効にする](https://qiita.com/kawax/items/69e921fe03d7a5d29b54)

#SSH鍵ファイル作成
Homestead.yaml の authorize と keys にあたるファイルを作成します

```yaml:Homestead.yaml
authorize: ~/.ssh/id_rsa.pub # 公開鍵

keys:
    - ~/.ssh/id_rsa # 秘密鍵
```

```bash:GitBash
cd ~

# 鍵が既にあるかどうか
ls -la .ssh

# 無ければ以下を実行

mkdir .ssh
cd .ssh # ~/.ssh へ移動

# 鍵ファイル作成
ssh-keygen -t rsa

# id_rsa.pub と id_rsa が作成されたことを確認する
ls -l
```

#hostsファイル修正
`C:\Windows\System32\drivers\etc\hosts` にホスト追加します。
これはGit Bashで編集できなかったのでサクラエディタでやっちゃいました。

```bash:GitBash
# Homestead.yamlの ip と sites:map を紐づける感じです
192.168.10.10    homestead.test
```

#いざ、起動！

```bash:GitBash
# Vagrantfileがある場所に移動
cd Homestead/

# 起動　ちょっと時間かかります
vagrant up
```

## 502 Bad Gateway になった
起動して `vagrant ssh` もできる状態になったのですが、
`http://homestead.test` をブラウザで開くと502の表示……

どうやら原因はnginxの方にあるらしい
[502 Bad Gateway nginx (1.9.7) in Homestead [ Laravel 5 ]](https://laracasts.com/discuss/channels/general-discussion/502-bad-gateway-nginx-197-in-homestead-laravel-5?page=1)

というわけで、nginxの設定を見ていきます

```bash:GitBash
# homestead環境にログイン
vagrant ssh

# nginxの設定ファイルはこちら
less /etc/nginx/nginx.conf
```

「Virtual Host Configs」の項に何がincludeされているか書いてます

```bash:/etc/nginx/nginx.conf
http {
# (中略)
        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}
```

includeしているディレクトリを見ると、
どうやら `/etc/nginx/sites-available/homestead.test` がhomestead環境の設定ファイルのようです。

```bash:/etc/nginx/sites-available/homestead.test
server {
# (中略)
    access_log off;
    error_log  /var/log/nginx/homestead.test-error.log error;
```

エラーログの場所が分かったので、そちらを見ます。
(と言いつつ、調査当時のメモによるとなぜか `homestead.app-error.log` の方を見ている私…)

```bash:/var/log/nginx/homestead.app-error.log
2019/01/17 04:20:09 [crit] 1603#1603: *1 connect() to unix:/var/run/php/php7.2-fpm.sock failed (2: No such file or 
directory) while connecting to upstream, client: 192.168.10.1, server: homestead.app, request: "GET / HTTP/1.1", up
stream: "fastcgi://unix:/var/run/php/php7.2-fpm.sock:", host: "homestead.test"
```

php-fpmの方に原因がありそう。
類似のエラーを対処した方の記事を見ながら修正してみます。
[nginxでphpのパッケージを追加したら’502 Bad Gateway’になってしまったときの対処法](http://kawatama.net/web/1352)

```bash:vagrant@homestead
sudo vi /etc/php/7.2/fpm/pool.d/www.conf

# www.confのlistenを修正
;listen = /run/php/php7.2-fpm.sock
listen = /var/run/php/php7.2-fpm.sock
```

そしてphp-fpmとnginxを再起動します

```bash:vagrant@homestead
sudo service php7.2-fpm restart
sudo service nginx restart
```

これで502エラーが解消されました！

##No input file specified が表示される

[こちら](https://qiita.com/ricoirico/items/9745160bcf9983fa30ad#no-input-file-specified%E3%81%8B%E3%82%89%E5%A4%89%E3%82%8F%E3%82%89%E3%81%AA%E3%81%84%E3%82%93%E3%81%A0%E3%81%91%E3%81%A9) によると
`Homestead.yaml` の `sites:to` のディレクトリが間違っているかもということで確認しましたが、私の場合その問題ではなさそうです。

```bash:vagrant@homestead
ls -l ~/code/public/index.php
-rwxrwxrwx 1 vagrant vagrant 1823 Jan 17 04:56 /home/vagrant/code/public/index.php

# Homestead.yamlの設定は以下のようになっているので問題なし
sites:
    - map: homestead.test
       to: /home/vagrant/code/public
``` 

というわけで、エラーログをtailしながら `http://homestead.test` に再度アクセス。

```bash:/var/log/nginx/homestead.app-error.log
2019/01/17 05:16:18 [error] 7864#7864: *6 FastCGI sent in stderr: "Unable to open primary script: /home/vagrant/code/test/public/index.php (No such file or directory)" while reading response header from upstream, client: 192.168.10.1, server: homestead.app, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/var/run/php/php7.2-fpm.sock:", host: "homestead.test"
```

なぜか `/home/vagrant/code/test/public` を見に行っている模様。

実は最初の頃Homestead.yamlを以下のように設定していた時期があり、その時の設定が適用されたままだったようです。

```yaml:Homestead.yaml(古い設定)
sites:
    - map: homestead.app
      to: /home/vagrant/code/test/public
```

エラーログが `homestead.app-error.log` の方に出ていたのもそれが原因です。
強制プロビジョニングで解消しました。

```bash:GitBash
vagrant up --provision
```

これで例の初期画面が表示されました。
その後、エラーログも `/var/log/nginx/homestead.test-error.log` の方に出力されるようになりました。

お疲れ様でした……！


#その他参考
* [Laravel 5.7 Laravel Homestead](https://readouble.com/laravel/5.7/ja/homestead.html)
 * これだけを見て何とかしたかったですね(何とかならなかった)
* [Vagrant + VirtualBoxでWindows上に開発環境をサクッと構築する](https://qiita.com/ozawan/items/160728f7c6b10c73b97e)
* [Windows10でLaravel Homestead環境構築](https://qiita.com/ricoirico/items/9745160bcf9983fa30ad)
* [Laravel 開発環境の構築 ( VirtualBox + Vagrant + Homestead + Composer + Eclipse ) 第1回 -前編-](https://qiita.com/slangsoft/items/21e5cc5015ff71e2f741)
* [【Laravel超入門】開発環境の構築（VirtualBox + Vagrant + Homestead + Composer）](https://qiita.com/7968/items/97dd634608f37892b18a)
* [Homestead で、Laravel 開発環境を構築する手順](https://qiita.com/oreo3@github/items/1705b133e00019800ff6)
* [【Vagrantドキュメント意訳】09.プロビジョニング](https://qiita.com/ringo0321/items/38743442a9abfc3be5b2)