Xampp環境で開発したReact x Laravel x mysql のアプリケーションをherokuにデプロイする。

#はじめに
開発したアプリケーションをherokuにデプロイしようと思ったのですが、使用した技術的にもあまり適当な情報がなかったので備忘録としてまとめるついでに誰かの役にたてばなと思います。環境がLinuxですのでMacの方は適宜読み替えてください。様々なサイトを参考にさせてもらっており、参考文献として最後に載せています。

#環境
Ubuntu20.04LTS
React
Laravel(php)
mysql
xampp

#前提
linuxのコマンドが触れる
gitを扱える
デプロイの概念がなんとなく分かる
laravelアプリケーションフォルダ直下をgitで管理している

#herokuの登録とClearDBの設定
こちら[[1]]から登録します。２段階認証みたいなやつはなんか飛ばしちゃいましたが、やっといた方が良い気がする。ログインまで行けたら**Create new app**を選択してアプリケーションの作成をします。名前を入力して、リージョンはアメリカとヨーロッパしかないのでアメリカを選択。**Overview**を押した後に**Configure Add-ons**を押すと**Add-ons**と書いてある検索欄が出てくるのでそこに**ClearDB**と入力して出てきたものをクリック。更に**Ignite-free**をクリックすると赤い警告のようなものが出てくるので、そこにある下の方のリンクをクリックします。

ここで一旦ここまでの流れを解説します。herokuではデフォルトのDBはpostgreSQLなのでアドオン（拡張機能）を用いてmySQLを使用出来るようにする必要があります。そのアドオン名がClearDBです。その後利用プランを無料のものに選択ししましたが、このアドオンの利用には条件があります。それがクレジットカードの登録です。赤い警告ではクレジットカード登録しろといっているのでリンクをクリックして登録しようとしているという流れです。

リンクをクリックするとクレジットカードの番号、名前、住所などの入力画面が出てくるのですべて英語で入力してください。こちらのサイト[[2]]で日本語住所を変換すれば簡単に英語になるようですが、順番とか間違えない人だったらそのまま英語で入力しても大丈夫です。完了したら先程の画面に戻って**ClearDB**の下にある**Submit Order Form**を押したら完了です。

#環境変数の設定
**Settings**を押した後、**Reveal Config Vars**を押すと環境変数の追加画面が出てきます。左側の**KEY**の部分に環境変数名を、 **VALUE**の部分にその値を入力すれば環境変数を設定することが出来ます。環境変数CLEARDB_DATABASE_URLのURLの部分に色々な情報が含まれているので、それを環境変数として抜き出して使いやすくします。形式は下の形です

```bash
mysql://ユーザー名:パスワード@ホスト名/データベース名?reconnect=true
```
そして以下のような対応で環境変数を作成します。

```
KEY:VALUE
DB_CONNECTION:mysql
DB_HOST:ホスト名
DB_PORT:3306
DB_DATABASE:データベース名
DB_USERNAME:ユーザー名
DB_PASSWORD:パスワード
```
次にアプリケーション用の環境変数**APP_KEY**と**APP_URL**の設定を行います。laravelの環境で以下のコマンドを実行します。

```
php artisan key:generate --show
```
このコマンド後に表示されたkeyがAPP_KEYになります。base64の部分も含めます。ちなみにbase64はデータの表現方法の一つで、暗号ではないのでこのkeyは盗まれないようにしましょう。ただこのコマンドはキーを生成してそれをコンソール上に表示しているようですが、そもそもlaravelの設定時にAPP_KEYを.envファイルへ書き込んだ気がします（事実書いてあった）。こっちでも良さそうな感じあるんですが、一応参考サイト通りに生成してそっちを書いておきました。

**APP_URL**は以下の形式です

```
https://Herokuのアプリケーション名.herokuapp.com
```
この2つの環境変数を追加しましょう。メール機能などがあればもっと環境変数が必要になりますが、僕のアプリケーションにはないので省略します。

#ビルドやマイグレーション時の設定
先程のページの下にある**Add　Buildpack**ボタンを押した後、ポップアップが出てくるのでnodejsを選択した後に**Save Changes**を選択。もう一度phpで同じことをします。ここらへんはよくわかってないですが、ビルドに要るんだろうなあという感じです。

次にローカルのpackage.jsonの編集を行います。下記のスクリプトをpackage.jsonに追加します。スクリプトは既に存在するはずなので追記するだけでいいです。

```json
"scripts": {
        "heroku-postbuild": "npm run prod" 
},
```

次にアプリケーションを動かすためのコマンドを記述するファイルであるProcfileを作成していきます。laravelアプリフォルダ直下にProfileというファイル（拡張子なし）を作成して以下の内容を記述します。

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

とりあえずこうすればいいんでしょうが、よく分からなかったので調べてみたところProcfileの書き方は

```
process type : command
```
という感じらしいので、今回はwebという process typeでなんかコマンド実行してるっぽいですね。xamppもapacheで構成されてますし、なんかそこらへんのコマンドなんでしょう。もやもやしますが、深堀りしすぎると性格上脱線しやすいのでここら辺にしておきます。

次にvarchar型の文字数の制限をします。laravel,heroku,デプロイで検索すると複数ヒットしますが、どうやらvarchar型の文字数制限を191にしないとマイグレーション時にエラーが出てしまうようです。このエラー対策としてapp\Providers\AppServiceProvider.phpを下記のように書き換えましょう。

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

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

#Heroku CLIでの操作
Heroku CLIのインストールの前に少しだけ解説をしておくと、CLIはCommand Line Interfaceの略で、全部文字でやろうね的なやつです。これと対比されるのがGUIで、視覚的でこちらの方が一般的だと思います。とりあえずここで理解しておいてほしいのはHeroku CLIはherokuを文字（コマンド）で操作するためのものだということです。要するにターミナルでheroku操作したいからHeroku CLIインストールしようという流れです。

こちらのページ[[3]]から自分が使ってるOSのコマンドをコピペしてインストールしてください。僕はUbuntuなので下記コマンドになります。

```
sudo snap install --classic heroku
```

ダウンロードが終わったらログインをします

```
heroku login
```
ここで参考サイトとは異なりメッセージが表示される

```
コマンド 'heroku' は '/snap/bin/heroku' で利用できます
'/snap/bin'がPATH環境変数に含まれていないためコマンドを特定できませんでした。
heroku: コマンドが見つかりません
```
どうやらパスが通ってないようなので.bashrcにパスを追加して更新。

```bash
export PATH="/snap/bin:$PATH"
```

macだとzshになってたりすると思いますが、適宜置き換えてください。

もう一度ログインするとコマンド自体は成功

```
 ›   Warning: Our terms of service have changed: https://dashboard.heroku.com/terms-of-service
heroku: Press any key to open up the browser to login 
```
なんか警告出てるので見てみると、利用規約の変更があったっぽい。読んだが特に問題なさそうだったのでスルーしてもう一度実行

```
 ›   Warning: heroku update available from 7.59.0 to 7.59.1.
heroku: Press any key to open up the browser to login or q to exit: 
```
今度はアップデート出来るよと出てるので調べてみると、単純にアップデートすればいいらしい。

```
heroku update
 ›   Warning: update with: snap refresh heroku
heroku: Updating CLI... not updatable
```
としたらまたエラー。調べてみると似たような内容の記事が出てきたのでコマンドを実行

```
sudo snap refresh 
All snaps up to date.
```
うまくいったかと思いもう一度ログインを試みるも、さっきと同じエラーが出た。もう一度検索してみると違うコマンドが載っていたのでそちらを実行

```
source <(curl -sL https://cdn.learnenough.com/heroku_install)
```
curlで取ってきて更新してるっぽい。これで警告はでなくなった。警告放置しておくと後々面倒になることが多いので良かった。最終的には一番下のコマンドを実行すれば良かったっぽい。

警告もなくなったので続きにもどる。最初のコマンドの入力したあとEnterキーなどを押すとサイトが開いた。自分の場合はメールアドレスやパスワードなどは入力しなくてもログインボタンを押すだけでログインできた。恐らくクッキーで保存してるからだと思うので、してない人は入力すればいけるはず。ログインボタンを押すとコンソールの方にログインしたと出力が出来たので、とりあえずCLIでログインすることには成功。

#デプロイとマイグレーション
herokuではデプロイする場合、herokuリモートリポジトリのmaterブランチにローカルリポジトリのmasterブランチからプッシュすることでデプロイすることが出来ます。一応masterブランチ以外からでもデプロイ出来るようですが、基本的にはデプロイ前にはマージしてmasterブランチを更新しておいた方が良さそうです。

設定も色々変えているので、masterへのマージとプッシュしてあることを確認したら、下のコマンドを実行します。

```
heroku git:remote -a herokuのアプリケーション名
set git remote heroku to https://git.heroku.com/herokuのアプリケーション名.git
git push heroku master
```
これで一応アプリケーションのデプロイは完了です。最後のコマンドの後に出てくるURLをクリックすることでも、自分のアプリケーションのサイトに飛べますし、下記コマンドでも開けます（herokuにアプリケーションが複数ある場合は違うコマンドかも）

```
heroku open
```

しかしアプリケーションをwebで開いてみると、真っ白になっている。デベロッパーツールのコンソールを見てみると下記のエラーが

```
Mixed Content: The page at 'https://frote.herokuapp.com/' was loaded over HTTPS, but requested an insecure script 'http://frote.herokuapp.com/js/App.js'. 
This request has been blocked; the content must be served over HTTPS.
```
どうやらHttp接続をしているようだが、どこかよく分からない。言われているのがビルド後のReactファイルなのでコードの中身ではなさそうと判断し、色々と情報を調べているとこのサイト[[6]]の一番最後に同様のエラーに対する対処が書いてあった。この手のサイトあまり信用していないのですが、あまりに情報がないのでとりあえず実行。下記のような環境変数を追加

```
Key : Value
ASSET_URL : https://herokuのアプリケーション名.herokuapp.com
```
これを追加したところ表示された。正直なんでかよく分かっていないので調べたが全然情報が出てこない。恐らくhttps通信にすることが出来たのだろうが、そもそも何が原因だったのか。とりあえず動いたので一旦このままにしておくが、後々原因を究明したほうが良さそう。何か分かる人いたら教えてください。

とりあえず表示までは出来たのでDBを使用するためにマイグレーションしていく。下記コマンドでマイグレーション

```
heroku run php artisan migrate
```
コマンド入力後に**Do you really wish to run this command? (yes/no)**と聞かれるのでyesと入力。しかしエラーが出て、試行錯誤しているうちに既にテーブルが作成されているためマイグレーションがうまく行かなくなってしまった（エラーを保存し忘れていました。すみません）。コマンドを見る感じheroku runのあとにartisanコマンドが出来そうなので、下記コマンドでデータベースの再構築を試みる。

```
heroku run php artisan migrate:refresh
```
しかし、同様にテーブルが存在するので無理だとエラーが出る。色々と調べてみるとこちら[[7]]でrefreshでなくfleshならうまくいったと書いてあったので実行してみる。

```
heroku run php artisan migrate:fresh
```
このコマンド後にマイグレーションに成功。2つのコマンドの違いを調べたところrefleshはロールバックしてから実行するのに対し、freshは削除してから実行しているよう[[8]]。何回も実行していたのでロールバックしても同じような状態だったのかもしれない。この後に動作確認をしたが、プログラム通りではない動作は存在しなかった（本番環境になったことで見えてきた修正点はあったが）。とりあえずデプロイ自体は完成したよう。

#その他調整
**アプリケーション名の変更**
アプリケーション名を開発環境だと適当にしていたので、本番環境で名前を変えたくなった。環境変数に以下を追加で解決。

```
key:value
APP_NAME : アプリケーション名
```
**herokuをスリープしないようにする**
herokuは無料枠だと30分でスリープしてしまう。その対策法として一定時間ごとにcurlコマンドでアクセスするというのがあったのでやってみた。

アドオンを追加

```
 heroku addons:add scheduler:standard
```
Herokuのブラウザアプリにアクセスし、shedulerをクリック。**Add Job**をクリックし、Run Commandの部分に下記コマンドを入力

```
curl herokuアプリケーションのURL
```
で完了。（デフォルトで10分ごとに実行するようになっているはず）

#デプロイ後のアプリケーションの感想
**遅い！**herokuは遅いから辞めておけという記事を見て、まあ言うほどでもないやろと思っていたが結構遅い。おかげでローディング時のUIの大切さの理解や遅すぎて動作がはっきり見えるためデバッグしやすいなどの利点もあったが、これは不便さを感じるレベルで無理ですね。まあ無料でこんな簡単に利用してる側が文句言うのはおかしな話なので感謝しなければならないのですが。リージョンに東京がないためアメリカにしているのが結構効いてそうですね。やはりちゃんとしたサービスを展開したいならAWSなどの方が良さそう（やったことないのでどうなのか分かりませんが）。とはいえ完全無料でここまで出来るので、勉強がてらデプロイの理解などをするにはちょうど良さそう。

一応デプロイしたアプリケーションtoDoリストアプリケーションFroteはこちら[[9]]になります。


#おわりに
超簡単という感じでは無かったですが、ちゃんと調べればデプロイは手軽に出来ると思います。ただ自分の真剣に作ったアプリケーションをherokuにデプロイしようとはちょっと思えませんでしたね。アプリケーションの修正とCI/CDだけしたらAWSに移行しようと思います。

#参考文献
[1]:https://www.heroku.com/home
[2]:https://kimini.jp/zip_addresses/index/3703504
[3]:https://devcenter.heroku.com/articles/heroku-cli#download-and-install
[4]:https://qiita.com/skyfish20ch/items/2e74df1c9ac4209e3e62
[5]:https://qiita.com/Panzo_webengineer/items/4af03a15d6cfeb6cd643
[6]:https://ichi.pro/heroku-ni-reactjs-asetto-o-shiyoshite-laravel-8-web-saito-o-depuroi-suru-95804040757735
[7]:https://teratail.com/questions/204343
[8]:https://hara-chan.com/it/programming/laravel-migrate-commands/#_php_artisan_migraterefresh
[9]:https://frote.herokuapp.com/
[10]:https://ayaka-weblog.com/programming/laravel/laravel-heroku/


[[1]]:heroku
[[2]]:君に届け
[[3]]:The Heroku CLI
[[4]]:Herokuコマンド　アップデート
[[5]]:Heroku コマンド を最新バージョンにアップデートする方法
[[6]]:HerokuにReactjsアセットを使用してLaravel8Webサイトをデプロイする
[[7]]:マイグレーション実行によってHeroku上に作成されたテーブルを消して、再度マイグレーションする方法
[[8]]:(Laravel) migrationやり直しコマンドあれこれ
[[9]]:Frote
[[10]]:Laravelをherokuにデプロイする方法・手順の解説（MySQL使用）〜コマンドを使わず、Herokuのサイト上で設定するよ！〜