Ishida-IT LLC

< Back

DockerでNode.jsアプリケーションを開発する (4) Herokuにデプロイする

Posted: 2019-11-26

前回まで3回にわたって Node.js/Express.js, MySQL で簡単なアプリケーションを作成して来ましたが、今回は作ったものをいよいよインターネット上に公開する方法を見ていきたいと思います。

ホスティングサービスの検討

Webアプリケーション(もしくはWebサイト)をインターネット上に公開する方法はたくさんあります。

まずサーバー側でアプリケーションのプロセスを動かす必要がなくHTML/CSSやJavaScriptなどの静的なアセットを配信するだけのサイトであれば、ざっと考えても、

などのサービスが挙げられます。どれもほぼ無料で使える枠があるので気軽に試すことが出来ます。

ただ今回作成しているアプリケーションはNode.jsでリアルタイムに動く動的なWebアプリケーションなので、それに対応したホスティングサービスを検討する必要があります。

まず考えられるのは、様々なVPSや AWS EC2、Azure VM, GCP Compute Engine などのクラウドで動く仮想マシンのサーバー(IaaS)上にアプリケーションをデプロイする、という方法です。

この方法はこれで自由度が高くて良いのですが、逆に言うとサーバーのOSの管理まで含めて全て自分で行わなければならないので、メンテナンスコストが高くつきます。

そこで次に考えられるのは、以下のようなPaaSサービスです。

今回あらためて検索して見たのですが、Node.jsに対応したPaaSサービスでそれなりの実績がありそうなものというと、意外に多くはありませんでした。

最近の流れとしては、「PaaS」ではなく、Firebase Cloud Functions や AWS Lambda, Zeit Now などを使った「Serverless」な構成の人気が高まって来ているようです。

Node.js/Express.jsで作成したアプリケーションをサーバーレスな環境で動かすことも可能ではあるのですが、それはそれでまた考慮しないと行けないことも増えてくるので、今回は十分な実績と人気があるHerokuを使うことにしたいと思います。



さて、そういうわけでまずはHerokuの公式ドキュメントに目を通しておきましょう。

Getting Started on Heroku with Node.js | Heroku Dev Center
https://devcenter.heroku.com/articles/getting-started-with-nodejs

Deploying Node.js Apps on Heroku | Heroku Dev Center
https://devcenter.heroku.com/articles/deploying-nodejs

以下、これらのドキュメントの流れに従って作業して行きます。

Heroku CLIをインストール

下のページの通りにHeroku CLIをダウンロードしてインストールします。

https://devcenter.heroku.com/articles/getting-started-with-nodejs#set-up

Heroku CLI

私の場合はMacなのでbrewでインストールしました。

brew install heroku/brew/heroku

インストール出来たらCLIでHerokuアカウントにログインします。

heroku login


Heroku CLIでデプロイ

次にデプロイするのですが、今回のサンプルプロジェクトではアプリケーションのソースコードがプロジェクトのルートフォルダではなくその一階層下のsrcフォルダになっているので、デプロイする前に少しだけ工夫が必要です。

まず、srcフォルダのpackage.jsonファイルとは別に、プロジェクトのルートフォルダに「Herokuにデプロイするため」だけのpackage.jsonファイルを作成します。

Herokuではルートフォルダにpackage.jsonがあるかどうかを見てNode.jsアプリケーションであることを判定しているために必要になります。

“start”でsrcフォルダ内のエントリポイントを指定していることと、”heroku-postbuild”で「–prefix=src」を付けてnpm installを実行するようにしていることに注目してください。

package.json (プロジェクトのルートフォルダ)

{
  "name": "docker-nodejs",
  "version": "1.0.0",
  "scripts": {
    "start": "node src/bin/www",
    "heroku-postbuild": "npm i --prefix=src"
  },
  "engines": {
    "node": "12.x"
  }
}

また、これは無くても多分問題ないと思うのですが、一応プロジェクトのルートフォルダに「Procfile」というファイルを配置しておきます。

Procfile (プロジェクトのルートフォルダ)

web: node src/bin/www


ではHeroku側にアプリケーションを作成しましょう。

heroku create 


上で追加したファイルなどをGitにコミットしておきます。

git add .
git commit -m"Add deploy settings for Heroku"


その後、下のコマンドでHerokuにデプロイ出来ます。

git push heroku master

これ以降アプリケーションに変更を加えた場合は、Gitにコミット → herokuにプッシュ、という流れで更新していくことになります。



デプロイでエラーが起きなければ、下のコマンドでブラウザを開いてアプリケーションにアクセス出来ます。

heroku open

今はまだHeroku側でMySQLの設定を行っていないので、DB接続でエラーになってしまうと思います。

Heroku Deploy

下のコマンドでアプリケーションから出力されるログをリアルタイムに確認することが出来ます。

heroku logs -t

赤丸の部分でDB接続エラーになっていることが分かります。

Heroku DBError



URLの末尾に/users を付けるか、または

heroku open users 

を実行するとダミー文字列のレスポンスが返ってくるはずです。これは現状のソースコードでは /users のルートハンドラが呼ばれた場合はDBアクセスを行っていないのでエラーにならないからです。

Heroku users



HerokuにMySQLデータベースを追加する

では下のドキュメントに従ってMySQLの設定を行いましょう。

ClearDB MySQL | Heroku Dev Center
https://devcenter.heroku.com/articles/cleardb

まずアカウントにクレジットカード情報を登録してから、次のコマンドを実行します。(クレジットカードは本人確認のために必要で、無料枠の範囲内で使っている限り課金はされないそうです。)

heroku addons:create cleardb:ignite


MySQLのアドオンが追加出来たら、下のコマンドで接続情報を取得します。

heroku config | grep CLEARDB_DATABASE_URL

例えば、下のような結果が表示されたとします。

CLEARDB_DATABASE_URL: mysql://b7fcaxxxxxxxx:86efxxxxxxx@us-cdbr-xxxx-east-999.cleardb.net/heroku_b44fa6dxxxxxxxxx?reconnect=true

Node.jsのアプリケーション側でこのDB接続文字列をそのまま使ってDBに接続するようになっていればそれで良いのですが、今回のサンプルアプリケーションでは、

  • MYSQL_USER
  • MYSQL_PASSWORD
  • MYSQL_SERVER
  • MYSQL_DATABASE

の4つの環境変数を使うようになっているので、それに合わせて接続文字列を分解してHerokuの「Config Vars」として設定する必要があります。

DB接続文字列は、

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

となっているようですので、これを下の4つのコマンドに分けて設定します。

heroku config:set MYSQL_USER='b7fcaxxxxxxxx'
heroku config:set MYSQL_PASSWORD='86efxxxxxxx'
heroku config:set MYSQL_SERVER='us-cdbr-xxxx-east-999.cleardb.net'
heroku config:set MYSQL_DATABASE='heroku_b44fa6dxxxxxxxxx'


この状態で、

heroku open

を実行すると、今度はDB接続には成功しますが、「tasksテーブルが見つからない」というエラーが発生します。まだテーブルを作成していないので当然ですね。



HerokuコンソールからDBマイグレーションを実行する

Heroku側のMySQLにテーブルを作成したり初期データを投入したりするには、Herokuの「Dyno」と呼ばれるコンテナのシェルに接続して、DBマイグレーションを実行する必要があります。

heroku run bash

を実行するとDynoのシェルに接続出来ます。

ただ、手元で試したときには下のエラーが出て接続出来ないことが何回かありました。

Heroku Run Error

このエラーが出る場合は、下のWebコンソールを使う方法を試してみてください。

Herokuの管理画面の右上にある「More」というメニューを開いて、「Run console」をクリックします。

Heroku Console

このコンソール上で、

cd src
npx sequelize-cli db:migrate
npx sequelize-cli db:seed:all

を実行します。

Heroku Console Migrate

これでデータベースへのテーブル作成と初期データ投入が完了します。

heroku open

でアプリケーションが開いてタスク一覧画面が表示されれば、ついにインターネット上への公開が完了です!

Heroku Deploy

ソースコード

ここまでの全ソースコードは下記で確認出来ます。

https://github.com/ishidait/docker-nodejs/tree/blog-4