Ishida-IT LLC

< Back

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

Posted: 2019-11-27


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

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

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

サーバ側で動的な処理をおこなう必要がなくHTML/CSSやJavaScriptなどの静的なアセットを配信するだけであれば、ざっと考えても、

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

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

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

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

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

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

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

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


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

Getting Started on Heroku with Node.js | Heroku Dev Center

Deploying Node.js Apps on Heroku | Heroku Dev Center

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



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

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

> 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に接続するようになっていればそれで良いのですが、今回のサンプルアプリケーションでは、

の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