はじめに
開発したアプリケーションをherokuにデプロイしようと思ったのですが、使用した技術的にもあまり適当な情報がなかったので備忘録としてまとめるついでに誰かの役にたてばなと思います。環境がLinuxですのでMacの方は適宜読み替えてください。様々なサイトを参考にさせてもらっており、参考文献として最後に載せています。
環境
Ubuntu20.04LTS
React
Laravel(php)
mysql
xampp
前提
linuxのコマンドが触れる
gitを扱える
デプロイの概念がなんとなく分かる
laravelアプリケーションフォルダ直下をgitで管理している
herokuの登録とClearDBの設定
こちら[1]から登録します。2段階認証みたいなやつはなんか飛ばしちゃいましたが、やっといた方が良い気がする。ログインまで行けたら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の部分に色々な情報が含まれているので、それを環境変数として抜き出して使いやすくします。形式は下の形です
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に追加します。スクリプトは既に存在するはずなので追記するだけでいいです。
"scripts": {
"heroku-postbuild": "npm run prod"
},
次にアプリケーションを動かすためのコマンドを記述するファイルであるProcfileを作成していきます。laravelアプリフォルダ直下にProfileというファイル(拡張子なし)を作成して以下の内容を記述します。
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を下記のように書き換えましょう。
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にパスを追加して更新。
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]: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のサイト上で設定するよ!〜