Laravel + Heroku (on Vagrant)を最初から

## はじめに
Laravelを使って開発がしたい。本番デプロイのデモをHerokuでさくっと行いたい。
そんな私の需要に答えて、手順をまとめてみました。

## 前提
- Herokuにユーザ登録済
- VirtualBox, Vagrantをインストール済 (vagrant v2.2.4)
- Laravel Homesteadを使います
- 実行環境はwindows10使っています（macでも大丈夫）

## Homestead
<details>
<summary>Homesteadとは</summary>
<div>

Laravelをすぐに使える環境を提供してくれる優れたツールです。
>HomesteadはWindowsやMac、Linuxシステム上で実行でき、Nginx WebサーバとPHP7.2、PHP7.1、PHP7.0、PHP5.6、MySQL、PostgreSQL、Redis、Memcached、Node、他にも素晴らしいLaravelアプリケーションを開発するために必要となるものすべてを含んでいます。

</div>
</details>

公式通りにHomesteadのBOXを追加し、ソースをクローンします。

```shell:hostOS
vagrant box add laravel/homestead
git clone https://github.com/laravel/homestead.git ~/Homestead
```


Homesteadのバージョンはこの時点で最新のタグを使用しています。

```shell:hostOS
cd ~/Homestead
git tag --list
> etc...
> v8.1.0
> v8.2.0
git checkout v8.2.0
# 設定ファイルの生成
bash init.sh
```

設定ファイルの変更

```yaml:Homestead.yaml
# mariaDBを使う場合は追記
mariadb: true

folders:
    - map: C:/Site/
      to: /home/vagrant/code

sites:
    - map: homestead.test
      to: /home/vagrant/code/homestead/public
    - map: laravelapp.test
      to: /home/vagrant/code/laravelapp/public

databases:
    - homestead
    - laravelapp
```

私の場合はCドライブ直下に`Site`ディレクトリを作成し、その中に各プロジェクトをまとめています。
`sites`では上記のように複数設定することができますので、`to: /home/vagrant/code`より使いやすいです。

Homesteadを立ち上げます。

```shell:hostOS
vagrant up --provision
```

ただ通常、作業は各プロジェクトで行うため、どこからでも起動できることが望ましいです。
エイリアスを登録しておくと捗るでしょう。

```shell:hostOS
alias homestead='function __homestead() { (cd ~/Homestead && vagrant $*); unset -f __homestead; }; __homestead'
```

コマンド自体はvagrantと同じです。

```shell:hostOS
# vagrant upが済んでいたら実行しなくていいです
homestead up --provision
```

起動には時間がかかりますので、今のうちにプロジェクトに移動します。
そしてエディタを立ち上げます（VsCode使っています）。

```shell:hostOS
cd /C/Site/homestead
code .
```

`Ctrl+@`を叩いてターミナルを開きます（Mac:Ctrl+Shift+@)。
windowsの場合はGitBashが開くようにしておくと少し幸せかもしれません。

今のうちに`hosts`の設定もしておきます。

```shell:windows
powershell -NoProfile -ExecutionPolicy unrestricted -Command "start notepad C:\Windows\System32\drivers\etc\hosts -verb runas"
```

windowsは`windowsキー+R`を押してコピペすると管理者権限でファイルを開くことができます。
macの場合はターミナルのまま普通に開きます。

```shell:mac
sudo vi /etc/hosts
```

hosts設定

```text:hosts
# Homestead.yamlでIP変更できます
192.168.10.10 homestead.test
```

さて、仮想環境が起動したらゲストにSSH接続します。

```shell:hostOS
homestead ssh
```

「homestead」と大きな文字で迎えられたら成功です。

## laravelプロジェクトを立ち上げる

まずはプロジェクトに移動します。

```:guestOS
cd ~/code/homestead
```

Laravelのプロジェクトを作成します。今回は`5.7`にします。

```:guestOS
composer create-project laravel/laravel ./ --prefer-dist "5.7.*"
```

起動したら一度、アクセスしてみます。表示されました。

- [http://homestead.test](http://homestead.test)

ここでGit管理しておくといいと思います。

```shell:guestOS
git init
git add .
git commit "first commit"
```

windowsの場合、`.gitattributes`の`* text=auto`をコメントアウトしてしまいますがどうなんでしょうね（ひとりごと）。

## Herokuにログインする

homestead環境でHerokuにデプロイしたいと思います。
herokuをCLIで操作するためのコマンドを実行します。

```shell:guestOS
sudo snap install heroku --classic
```

herokuにログインします。「なにかキーを押してね」と言われるので押します。

```shell:guestOS
heroku login
> heroku: Press any key to open up the browser to login or q to exit:
```

すると、herokuのログイン画面がブラウザで自動的に開きます。
…ゲスト側なので開きませんね。
開かない場合も、下記のようなメッセージが出てきますので、指定URLに手動でアクセスしましょう。


```shell:guestOS
Warning: Cannot open browser. Go to https:<ごにょごにょ>
```

これでHerokuにログインできました。

## Herokuにデプロイ

デプロイする前に`Procfile`を作成する必要があります。
linuxの`ps`コマンドで確認できるようなプロセスを起動できるみたいです。
詳しく知りたい方は公式へゴーゴゴー！

[The Procfile \| Heroku Dev Center](https://devcenter.heroku.com/articles/procfile)

今の私のざっくりした認識は「WEBサーバを○○で起動するためのコマンド」です。
今回はwebサーバにapacheを使用しますので、下記のように記述します。

```Procfile
web: vendor/bin/heroku-php-apache2 public/
```

ちなみに`public/`はバーチャルホストで設定するときのドキュメントルート指定みたいなものなので、記述しない場合は`homestead.test/public`にアクセスしないと表示されませんし、色々不都合が起きます。

さて、再度コミットした後、プロジェクトをherokuと関連付けます。

```shell:guestOS
heroku create
# または任意の名前でcreate
heroku create homestead
```

これで`git remote -v`でリモート情報に`heroku`が追加されていることが分かるでしょう。
あとは下記コマンドでデプロイをします。

```:guestOS
git push heroku master
```

このコマンド時に色々と処理が走っているのが目で見て分かると思います。
ここで内部的にアプリをビルドしているのですが、herokuは自動でコードを認識し、適切なビルドを行ってくれます。
ですが、phpとnode.jsなどのソースが混在していると誤認識される場合もあるようです。
その場合は下記のようにオプションを指定するか、

```shell:guestOS
heroku create --buildpack heroku/php
```

`buildpacks:set`コマンドで後付けの指定をしましょう。

```shell:guestOS
heroku buildpacks:set heroku/php
```

確認すると、適切なビルドが指定されていると思います。

```shell:guestOS
heroku buildpacks
> heroku/php
```

さて、デプロイが問題なく終わったところでブラウザで確認します。
…映っていませんので最後の仕上げを行います。

### Herokuでアプリ設定
Laravelプロジェクトを生成した際に`.env`ファイルもさり気なく生成されています。
`.env`は環境ごとに設定するファイルのため`.gitignore`で管理除外されています。
そのため、下記のようにHeroku用の設定をする必要があります。

```shell:guestOS
heroku config:set APP_NAME=Homestead
heroku config:set APP_KEY=$(php artisan key:generate --show)
heroku config:set APP_URL=https://homestead.herokuapp.com
heroku config:set SESSION_DRIVER=file
```

これで私の場合、正常に映りました。

## 最後に
公式サイトを見れば、どこかに載っている情報だったりしますが、最初はコマンドも暗記できていないのであちこち見に行って時間を消費ばかりしました。需要があるか分かりませんが、きっと未来の私はこれを見て喜ぶと思いますので書いてよかった。どや。

※サンプルとして`https://homestead.herokuapp.com`などと記述していますが、実際には`homestead`は作成していません。もし参考にされる場合は、各々頭で置き換えて実行してください。