Node.js + MySQLで作ったアプリをHerokuにデプロイする

# はじめに

今回初めてHerokuにアプリをデプロイしました。デプロイ記事はネット上にいくつもありますが、自分なりの作業手順、つまづいた点などを記述していきます。

# アプリ

POSTしたデータをDBに格納するだけのシンプルなアプリです
![storeddatamysql.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349049/8cba74e2-7985-669f-3b84-739e90ebda06.gif)


~~https://storedatainmysql.herokuapp.com/~~
現在アプリの都合でいったん削除しています

## 仕様
- Node.js
  - Express
  - ejs
  - body-parser
  - mysql


# 環境

- PC:Macbook Pro
- OS:MacOS Mojave Ver10.14.4
- エディタ: Visual Studio Code
- MySQLDB: 今回はherokuのアドオン`ClearDB`を使用します

# 前提条件

- Herokuに登録済み
- Herokuにクレジットカード登録済み（登録しないとアドオンが使用できません）
- Herokuインストール済み
- HerokuとCLIを紐づけている
- Node.jsインストール済み

# アプリをherokuにデプロイする

## CLIでの操作

- package.json作成<br>
`npm init`
- gitレポジトリ作成<br>
`git init`
- CLIからherokuにアプリを追加する<br>
`heroku create [アプリ名]`<br>
アプリ名は任意なので、書かない場合はherokuがランダムで生成してくれます。
- herokuをリモートレポジトリに紐付ける<br>
`heroku git:remote -a [アプリ名]`<br>
[アプリ名]の欄は先ほど追加したアプリ名に記述してください。わからない場合は、herokuのweb上からコードをコピペしてください。
![herokudeploy.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349049/994e580c-a31c-1795-eca3-e93f3e8587db.gif)

- とりあえずデプロイ<br>
初めてのデプロイで不安だったので、Expressの[hello world](https://expressjs.com/ja/starter/hello-world.html)を使用して実際に起動するか確認してみました
  1. `git add .`
  2. `git commit -m 'コミット名'`
  3. `git push heroku master`

ここまでが通常のデプロイ方法です。アプリはherokuのweb上`Open App`から開けます。と、ここでアプリが起動しませんでした。

## アプリが起動しない(問題点2つ)

### 解決1: `npm start`を設定し忘れていた

Node.jsでデプロイした場合、herokuではデフォルトで`npm start`から起動するようで、package.jsonでその設定をし忘れていました。

```js
 "scripts": {
    "start":"node app.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
```

しかし、それでもアプリは起動しませんでした。

### 解決2: ポート番号の設定方法を間違えていた。

待ち受けポートはHeroku側で設定されるので、`process.env.PORT`とコードに記述しなければいけません。本当にそうなのか固定ポートで試してみましたが、当たり前ですがやはり必要でした。

```js:app.js
app.listen(process.env.PORT || 5000)
```
このコードは`環境変数`と言い、これで実行時にサーバが指定したポートを受け取れるようです。`||`はローカルで実行した際に使用されるポートです。
[Node.jsのprocess.env.PORTとは何ですか？ - コードログ](https://codeday.me/jp/qa/20181209/56910.html)

これでアプリが正常に実行されるようになりました。

# MySQLを使用できるようにする

## ClearDBをインストール

CLIから今回使用するアドオンである`ClearDB`をインストールします。

```
heroku addons:add cleardb
```

## DBの情報を確認する

インストール後、自動でDBが作成されるので、情報を確認します。

```
heroku config | grep CLEARDB_DATABASE_URL
```
すると、以下のようなデータが出てきます

```
CLEARDB_DATABASE_URL: mysql://~~
```
このデータは以下のようになっています。

```
CLEARDB_DATABASE_URL: mysql://ユーザ名:パスワード@サーバ名/データベース?reconnect=true
```

## DBをセットする。
確認できたら、`mysql://~~`をコピーし、セットします

```
heroku config:set DATABASE_URL='mysql://~~'
```

これで、サーバーと接続することができました。後は個人的に先ほどのDBの情報を元にNodeとDBのコネクションを作成しました。

## Node:コネクションの作成

```js:app.js
const connection = mysql.createConnection({
  host: "サーバ名",
  user: "ユーザー名",
  password: "パスワード",
  database: "データベース"
});
```
## アプリが完成したらデプロイ

完成したら、再度herokuにデプロイします。

```
git push heroku master
```

しかし、アプリが起動しませんでした。

## アプリがまたまた起動しない(問題点1つ)

### エラーをlogで確認する

もし、アプリが起動しない場合、画面に`heroku log --tail`と出てくるはずなので、CLIに打ち込んでエラーを確認してみます。すると、

```
at=error code=H10 desc="App crashed" method=POST path="/register" host= ~~ request_id= ~~ fwd="~~" dyno= connect= service= status=503 bytes= protocol=https
```

このようなログを発見しました、ここで見たのは`code=H10 ``status=503`の２つです、この二つのコードを検索してみたら、どうやら接続ができずにタイムアウトしたようです。

### 解決: Webdynoを再起動してみる。

[HerokuでApplicationErrorが発生したときの対処法 - Qiita](https://qiita.com/Oakbow/items/1565922ddcdea0ce9ab5)
こちらの記事を参考に、以下のコードを実行しました。

```
heroku restart web.1 --app application_name
```

すると、アプリが起動するようになりました。

# 終わりに

初めてのデプロイでしたが、初心者でも半日あれば問題解決してデプロイできるくらいにHerokuは簡単でした。これからも簡単なアプリであればHerokuを使っていこうと思います。