Laravel・Vue.jsで作ったアプリをherokuで公開する


#参考サイト
主にこちらのサイトを参考にしながら進めていき、私が詰まった部分は随時追記していきたいと思います。

[Heroku+Laravel+MySQLを独自ドメイン(SSL)で公開する【Laravel6+Nuxt.jsで作る管理画面】](https://deha.co.jp/magazine/admin-laravel-nuxt-heroku-deploy/)

####開発環境

* Laravel：5.8.38
* Vue：2.6.12
* PHP：7.4.7
* Apache：2.2.34
* MySQL：5.7.26


#デプロイまで
###herokuコマンドのインストール

```
% brew tap heroku/brew && brew install heroku
```

###LaravelアプリケーションをHerokuへプッシュ

①(Herokuへのアカウント登録を済ませた上で)ルートディレクトリにてログイン

```
% heroku login
```

②Heroku上にアプリケーションの作成

```
% heroku create 自分で決めたアプリケーション名 --buildpack heroku/php
```
これでHeroku用のリモートリポジトリも作成されます。

③アプリケーションをHeroku（のリモートリポジトリ）にプッシュ

```
% git push heroku master:master
```

リモートリポジトリ、プッシュとはなんぞと言う場合は「サル先生のGit入門」がわかりやすいと思いました。
[履歴を管理するリポジトリ](https://backlog.com/ja/git-tutorial/intro/02/)



###ClearDBの設定

ClearDBのアドオンを使うことで、Heroku上でMySQLを利用することができます。

①クレジットカードの登録
https://dashboard.heroku.com/account/billing
ClearDBを使うには、Herokuマイページからクレジットカードの登録が必要です。
※有料版を使わなければ、課金される心配はありません。

②ClearDBをアドオンに追加

```
% heroku addons:add cleardb
```

③環境変数を設定しデータベース接続先をClearDBに設定する

下記コマンドで、ClearDBのデータベース情報を確認

```
% heroku config | grep CLEARDB_DATABASE_URL
```

すると、次のような形でデータベース情報が表示されます。

```
CLEARDB_DATABASE_URL: mysql://[ユーザー名]:[パスワード]@[ホスト名]/[データベース名]?reconnect=true
```

下記コマンドで、環境変数を設定します。

```
% heroku config:set DB_DATABASE=[データベース名]
% heroku config:set DB_HOST=[ホスト名]
% heroku config:set DB_USERNAME=[ユーザー名]
% heroku config:set DB_PASSWORD=[パスワード]
```

自分的には、Herokuのウェブサイト上から登録した方が間違いがなく楽でした。
Setting→Config VarsのReveal config Varsボタンから

![スクリーンショット 2021-01-30 21.03.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680199/5a17ac39-2ad3-b2cf-9996-6d0f87a93861.png)

こんな感じです。

###その他設定

####APP_KEY

APP_KEYとは？こちらがわかりやすいです。
[保存版！Laravelの.envでできること大全](https://blog.capilano-fw.com/?p=1382)
下記コマンドで設定できます。

```
% heroku config:set APP_KEY=$(php artisan key:generate --show)
```

####MySQLのインデックス用の文字列長の指定

Laravelでは、MySQLのバージョンが5.7.7より古いとマイグレーションを実行した際エラーが発生します。
[Laravel5.4以上、MySQL5.7.7未満 でusersテーブルのマイグレーションを実行すると Syntax error が発生する](https://qiita.com/beer_geek/items/6e4264db142745ea666f)

```
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was t
oo long; max key length is 767 bytes
```

ClearDBは最新バージョンでもMySQL5.5系らしく、文字列長の指定が必要になります。
`app/Providers/AppServiceProvider.php`に追記しましょう。

```php:app/Providers/AppServiceProvider.php
<?php

use Illuminate\Support\Facades\Schema;//追加

public function boot()
{     
    Schema::defaultStringLength(191);//追加
}

```

コードの修正をしたので、リモートリポジトリにプッシュして下さい。(結構忘れがち)

```
% git push heroku master:master
```

####WebサーバーにApacheを指定

①ルートディレクトリ直下にProcfileを作成して

```
% touch Procfile
```

②Procfileを編集

```
$(composer config bin-dir)/heroku-php-apache2 public/
```

ウェブサイトのResources内に書いてありました。
![スクリーンショット 2021-01-30 21.39.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680199/bf4ca2f1-665b-40d6-7cd6-7f6a049645cf.png)

調べるとこちらがよく出てくるのですが、私はエラーが出てうまくいきませんでした・・・

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

くどいですが、ファイル等に変更を加えたらリモートリポジトリにプッシュして下さい。(忘れがち)

```
% git push heroku master:master
```

#デプロイ後

###DBマイグレーション

```
% heroku run php artisan migrate
```
Heroku上で`php artisan`コマンドを使う場合は、その前に`heroku run`を付けます。
ここまで上手くいっていれば独自ドメイン設定に進んで大丈夫です。

####Seeder

※以下、seeder実行の際の思考錯誤ですので、seederを使わない場合は飛ばしてください。

#####エラー① `Class 'Faker\Factory' not found`

ダミーデータ作成のために

```
% heroku run php artisan db:seed
```

のコマンドを実行したところ、エラー。

```
Class 'Faker\Factory' not found
```

composer.jsonの`require`に`fzaninotto/faker`が入っていないことによるエラーです。（ローカルではエラーが発生しないなら、`require-dev`には入っているはず。）

[In DatabaseServiceProvider.php line 78:Class ‘Faker\Factory’ not foundがheroku上で出た場合の解決方法](https://www.trade-tech-note.work/heroku-laravel-faker-does-not-found/)

```json:composer.json
"require": {
"fzaninotto/faker": "^1.9"//追加
},
"require-dev": {
"fzaninotto/faker": "^1.4"
}
```

composer.jsonに追記し、ローカルで下記コマンドを実行。

```
% composer install
% composer update
```

ローカルのファイルに変更を加えていますので

```
% git push heroku master:master
```

heroku上(本番環境)で`fzaninotto/faker`をインストールするために下記コマンドを実行。

```
% heroku run composer install
% heroku run composer update
```


#####エラー② `Allowed memory size of 536870912 bytes exhausted`

すると、またエラー。

```
Allowed memory size of 536870912 bytes exhausted
```

処理に必要なメモリサイズがPHPで許容しているサイズを超えてしまったことによるエラーだそう。
[phpでmemory sizeエラーがでたときの対処法](http://webtech-walker.com/archive/2007/03/05152445.html)
いろいろ調べてphp.iniでメモリサイズの上限を変更しましたが・・・

```php:/php.ini
- memory_limit = 128M
+ memory_limit = 1024M
```

また同じエラーが出てしまいました。
こちらの記事を参考にしたのコマンド実行。
[composer updateでmemoryが足りない場合の対応方法 その2](https://polidog.jp/2018/12/14/composer/)

```
% heroku run COMPOSER_MEMORY_LIMIT=-1 composer update
```

これで`fzaninotto/faker`をインストールできました。
(php.iniを変更してもローカル上での動作にしか反映されないということでしょうか・・・？）

気をとり直して、下記コマンドを実行。

```
% heroku run php artisan migrate:fresh --seed
```

すると、またまたエラー。

#####エラー③ `Integrity constraint violation: 1452`

```
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails
```

外部キーエラーです。
[Heroku本番環境のMySQLデータベースをリセットする方法](https://qiita.com/take18k_tech/items/7afdde59d387fbde5f7e)
この記事を参考にMySQLにログインしテーブルを確認してみると・・・

```
mysql> select * from users;
+----+------------------+--------------------------------+
| id | name             | email                          |
+----+------------------+--------------------------------+
|  1 | 木村 陽一         | byamamoto@example.net          |
| 11 | 廣川 知実         | jun32@example.net              |
| 21 | 中津川 涼平       | takuma.nakatsugawa@example.com |
| 31 | 吉本 千代         | asuka83@example.com            |
| 41 | 鈴木 裕太         | maaya21@example.org            |
| 51 | 佐藤 太一         | yosuke96@example.com           |
| 61 | 小泉 加奈         | asuka.ito@example.org          |
| 71 | 田中 陽子         | hkato@example.org              |
| 81 | 喜嶋 康弘         | omatsumoto@example.net         |
| 91 | 中島 洋介         | ymiyake@example.org            |
+----+------------------+--------------------------------+

```

idが10刻みになっている・・・。なんという・・・
[herokuでmysql(ClearDB)を使うとidが10ずつ増える](https://qiita.com/nsatohiro/items/0458e63c47c3d6ff37d0)
ClearDBの仕様だそうです。
Seeder、Factoryファイルの書き方を工夫する等の必要がありそうですね。

私の場合、migrationファイルに書いた初期データのidも10刻みになってしまい困ったので、idを明記しました。

```php:create.categories.table.php
DB::table('categories')->insert([
    ['id' => 1, 'name' => 'PHP'],
    ['id' => 2, 'name' => 'Ruby'],
    ['id' => 3, 'name' => 'Java'],
    ['id' => 4, 'name' => 'C#'],
    ['id' => 5, 'name' => 'JavaScript'],
    ['id' => 6, 'name' => 'HTML/CSS'],
    ['id' => 7, 'name' => 'GO'],
]);
```

###独自ドメインの設定

独自ドメインの登録はこの記事の通りに進めれば大丈夫だと思います。エラーも起きませんでした。
[初めてHerokuで独自ドメインを公開するあなたへ](https://qiita.com/kenjikatooo/items/07c3d911210a4ca96781)


###サイトのSSL化

Herokuでは、有料プランにアップグレードすることでサイトのSSL化が可能です。
[SSLとは？httpsとは？簡単説明](https://jp.globalsign.com/ssl-pki-info/ssl_beginner/aboutssl.html)

HerokuウェブサイトのResources、Change Dyno Typeボタンから「Hobby」を選んでSaveボタンをクリック。（稼働分だけ、先に登録したクレジットカードから課金されますのでご注意ください。Saveを押したらすぐに課金されるわけではありません。）
![スクリーンショット 2021-01-31 21.14.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680199/7b4ae15b-f124-c5dd-82e1-eb64c0e5bb8b.png)

これでサイトのSSL化は完了です。しかし、httpsから始まる独自ドメインにアクセスすると、CSSが反映されていません。

[【Laravel】アクセス時に一時的にCSSが反映されない事象について](https://qiita.com/gatapon/items/024a96dc8c3bf52a9552)

####APP_ENVの設定

Setting→Config Varsから　APP_ENV:productionと設定
![スクリーンショット 2021-01-31 21.19.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680199/ead069ca-37b6-6cd6-886e-edc4a90941ac.png)

###httpsの強制

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

これでCSSがしっかり反映されるようになります。



###PHPの国際化用拡張モジュール

私はアプリの会員登録時のEmailバリデーションにEmail:spoofを使っていたのですが、実際に登録しようとしてみると`LogicException The Egulias\EmailValidator\Validation\SpoofCheckValidation class requires the Intl extension.`のエラーが発生しました。

[CakePHP3でintl導入時につまずいた事](https://qiita.com/machio77777/items/be29ca83992976afdcec)

うーん。いろいろ調べましたが、よく分かない。終わった・・・ここまで来たのに・・・と思いましたが、もっと調べていくと
[Laravel5.7: Herokuにデプロイする](https://qiita.com/sutara79/items/a173b969474d9f5afe1b)
Herokuでintlを使うには、Composerを通じて有効にしなければならないそうです。

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

続いて下記コマンドを実行して解決です。

```
% composer update
% git push heroku master:master
% heroku run composer update
```


以上です。参考にさせていただいた記事の投稿者の皆様、ありがとうございました。