【Heroku】LaravelとMySQLでデプロイする

# デプロイを行う

Laravelで一通りのCRUD機能が実装できたので、一度デプロイをしようと思う。本当は``AWS``で行った方が勉強になるのだが、事前知識の習得に時間がかかることと諸々の事情により、先に``Heroku``というサービスを利用してデプロイを行うことにした。

``デプロイ``とは、時と場合により意味が異なるようだ。今回は``アプリケーションを一般公開する``という感じで使用している。

``Heroku``は``PaaS(Platform as a Service、パース)``と呼ばれるサービスだ。本来、デプロイには様々な環境構築や設定が必要になるが、それを一手に提供してくれる。

他の``PaaS``には``Cloud9``が挙げられる。自分は今までLaravelで開発作業を行うために、自身で環境構築を行ってきた。しかし、Cloud9ではその必要がない。必要な環境は全て提供してくれる。このため、PaaSは初心者にとって非常にありがたいサービスである。

今は無事Cloud9を卒業できた。Herokuについても、今回は使用するがいずれ卒業したい。

# 作業環境

今回の作業は、以下の環境を前提として行っている。

- herokuがインストールされている。
- Herokuに登録済みである。
- Herokuにクレジットカードを登録している。

# 事前設定

## Herokuのアップデート

最初に``loginコマンド``でHerokuにログインする。

```
$ heroku login
heroku: Enter your login credentials
Email: メールアドレス
Password: **********
Logged in as メールアドレス
```

しばらく使用していなかったので、まず``updateコマンド``を実行する。ちなみにHerokuもHomebrewで管理されている。

```
$ heroku update
```

```
$ which heroku
/usr/local/bin/heroku
```

```
$ brew list
heroku
heroku-node
# 省略
```

## モジュールの追加

ここから、デプロイしたいアプリケーション（プロジェクト）のディレクトリに移動する。

```
$ cd larabbs
```

``intl（国際化用拡張モジュール）``は、Herokuでは自動で有効にならないため、``composer``を利用して有効にする。Herokuで使用する場合は、モジュール名の頭に``ext``が付くため、``ext-intl``として有効にする。

```
$ composer require ext-intl:*
```

``composer.json``で有効になっていることを確認できた。

```composer.json
# 省略
"require": {
    "php": ">=7.0.0",
    "ext-intl": "*",
    "fideloper/proxy": "~3.3",
    "laravel/framework": "5.5.*",
    "laravel/tinker": "~1.0"
},
# 省略
```

## サーバの設定

アプリを``Apache``で動かすために``Procfile``を作成し、必要な記述を行う。``public/``の記述により、``ドキュメントルート（外部公開されるディレクトリ）``を設定している。

```
$ touch Procfile
```

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

このまま作業を続けると、Herokuの``通信プロトコル``が``http``になってしまうそうだ。それを``https``に変更するため、``AppServiceProvider.php``へ以下の内容を記述する。

```AppServiceProvider.php
public function boot()
{
    if (\App::environment('production')) {
        \URL::forceScheme('https');
    }
}
```

# Herokuでアプリ作成

Herokuにアプリを作成する。``createコマンド``時にアプリ名を指定すれば、HerokuのURLにそれが反映される。（特に指定しなければランダムな単語で設定される。）アプリ名が既に使用されていた場合は、再登録を求められる。

なお、PHPを使用する場合は``buildpack heroku/php``オプションを忘れずに付けること。

```
$ heroku create [アプリ名] --buildpack heroku/php
```

ローカルリポジトリにcommit後、Herokuにpushできる。

```
$ git add -A
$ git commit -m "メッセージ"
```

```
$ git push heroku master
```

この段階でも、アプリ内にデータベースが関わらないページがあればビューの確認ができる。``openコマンド``を実行すると自動で規定のブラウザが起動し、アプリが開く。

```
$ heroku open
```

# HerokuでMySQLを利用

``MySQL``はHerokuのデフォルトではないため、``ClearDBアドオン``を利用する。これを利用するためにはHerokuへの``クレジットカード登録``が必須である。（登録しても、無料枠で使えば課金されることはない。）

自分がどのプランに設定されているか知りたい場合は、公式サイトにログインし``Dashboard``からアプリ名を選択後、``Resources``タブで確認できる。


早速``addons:addコマンド``を実行しよう。

```
$ heroku addons:add cleardb
```

実行後、``configコマンド``でHerokuの環境変数``CLEARDB_DATABASE_URL``が確認できる。（これは後で超重要になる！）

```
$ heroku config
=== [アプリ名] Config Vars
CLEARDB_DATABASE_URL: mysql://*****:*****@*****/*****?reconnect=true
```

# 環境変数の設定

ここが一番苦労した。これまでネットの情報を数多く利用してきたのだが、登録されている環境変数がサイトによって微妙〜〜に違う。環境が違えば登録する環境変数も違うことは当たり前だが、これが素人にとって大きな壁となる。

## 登録方法

登録は``config:setコマンド``で行う。内容を変更する場合は、同様のコマンドで上書きできる。

```
$ heroku config:set [環境変数]=[登録する内容]
Setting [環境変数] and restarting ⬢ [アプリ名]... done, v22
```

## 登録した環境変数

ここでは、自分が登録した内容を紹介する。もしかしたら必要のない環境変数もあるかもしれないが、参考になれば幸いである。

```
APP_DEBUG:            false
APP_ENV:              production
APP_KEY:              localと同じ
APP_NAME:             localと同じ
APP_URL:              https://[アプリ名].herokuapp.com
BUILDPACK_URL:        https://github.com/heroku/heroku-buildpack-php.git
CACHE_DRIVER:         localと同じ（file）
CLEARDB_DATABASE_URL: mysql://[DB_USERNAME]:[DB_PASSWORD]@[DB_HOST]/[DB_DATABASE]?reconnect=true
DB_CONNECTION:        localと同じ（mysql）
DB_DATABASE:          CLEARDB_DATABASE_URLの[DB_DATABASE]
DB_HOST:              CLEARDB_DATABASE_URLの[DB_HOST]
DB_PASSWORD:          CLEARDB_DATABASE_URLの[DB_PASSWORD]
DB_USERNAME:          CLEARDB_DATABASE_URLの[DB_USERNAME]
MAIL_DRIVER:          localと同じ（smtp）
MAIL_ENCRYPTION:      localと同じ（null）
MAIL_HOST:            localと同じ（smtp.mailtrap.io）
MAIL_PASSWORD:        localと同じ
MAIL_PORT:            localと同じ
MAIL_USERNAME:        localと同じ
QUEUE_DRIVER:         localと同じ（sync）
SESSION_DRIVER:       localと同じ（file）
```

注意すべきはデータベースの設定だ。自分は``CLEARDB_DATABASE_URL``の構成に気が付かなかった。そのためローカルと同じ環境変数を登録してしまい、ひたすらデータベースの作成に失敗していた；

正しい答えは全て``CLEARDB_DATABASE_URL``にあったのだ・・・

```
CLEARDB_DATABASE_URL: mysql://[DB_USERNAME]:[DB_PASSWORD]@[DB_HOST]/[DB_DATABASE]?reconnect=true
```

## データベースの作成

データベース関係の環境変数が誤っていると、延々とこのやり取りが繰り返される。

```
$ heroku run php artisan migrate:refresh
Running php artisan migrate:refresh on ⬢ [アプリ名]... up, run.2514 (Free)
**************************************
*     Application In Production!     *
**************************************

 Do you really wish to run this command? (yes/no) [no]:
 > y

**************************************
*     Application In Production!     *
**************************************

 Do you really wish to run this command? (yes/no) [no]:
 > y


In Connection.php line 664:

  SQLSTATE[HY000] [2002] Connection refused (SQL: select * from information_schema.tables where tab
  le_schema = [localのDB_DATABASE] and table_name = migrations)


In Connector.php line 67:

  SQLSTATE[HY000] [2002] Connection refused
```

正しい設定をして、ようやくデータベースの作成が出来た。

```
$ heroku run php artisan migrate
Running php artisan migrate on ⬢ [アプリ名]... up, run.7637 (Free)
**************************************
*     Application In Production!     *
**************************************

 
 Do you really wish to run this command? (yes/no) [no]:
 > y

Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table
Migrating: 2018_05_03_141933_create_articles_table
Migrated:  2018_05_03_141933_create_articles_table
Migrating: 2018_05_16_185519_add_user_id_articles_table
Migrated:  2018_05_16_185519_add_user_id_articles_table
```

なお、migrationは``heroku run php artisan migrate``ではなく、``heroku run bashコマンド``後に``php artisan migrate``を入力して実行することも可能だ。

```
$ heroku run bash
Running bash on ⬢ [アプリ名]... up, run.6059 (Free)
~ $ php artisan migrate
```

データベースの作成が完了したら、いよいよ``openコマンド``の実行だ。

```
$ heroku open
```

これで動作確認ができれば、作業終了。

# 参考情報

この方達の情報がなければ作業は出来なかった。本当にありがたい。

[Laravel5.6: Herokuにデプロイする](https://qiita.com/sutara79/items/a173b969474d9f5afe1b)
[Laravel5のお勉強 -第七回 Herokuにdeploy-](https://qiita.com/yu_eguchi/items/34fce39a07c79591f4af)
[HerokuでMySQLを使おうとして詰まったところ](https://qiita.com/senou/items/108ef1d94dcb5b227b4f) 
[Laravel5をpostgresqlでHerokuにデプロイ](http://kayakuguri.github.io/blog/2015/04/21/laravel5-on-heroku/)

これは[teratail](https://teratail.com)に自分が投稿した質問だ。上記サイト様に情報があったにも関わらず、見逃していた；
[【Heroku】LaravelでMySQLがmigrationできない。](https://teratail.com/questions/127060)

今回はここまで。