Skip to content
shunter1112 edited this page Aug 12, 2013 · 2 revisions

このチュートリアルはHerokuにデプロイされるNode.jsExpressウェブフレームワークについて扱って行きます。Herokuを使ったアプリケーションの開発や設計の仕方に関する一般的な情報は、Architecting Applications for Herokuを確認してください。

事前準備/前提条件

  • インストールされたバージョンのNode.jsとNPMを含んだ、基本的なNode.jsの知識。
  • あなたのアプリケーションは依存ファイルを管理するために、NPMを使用します。
  • Herokuのユーザアカウント。こちらで無料で簡単に取得ができます

ローカルの開発環境の設定

始めに、Heroku Toolbeltをローカルにインストール します。これはあなたのHeroku command-line client、Foreman、そしてGitのバージョン管理システムへアクセスを確かなものにします。

一度インストールできると、herokuコマンドがシェルから使えるようになります。アカウントを作ったときに使ったE-mailアドレスやパスワードを使ってログインしてみます :

:::term
$ heroku login
Enter your Heroku credentials.
Email: [email protected]
Password:
Could not find an existing public key.
Would you like to generate one? [Yn]
Generating new SSH public key.
Uploading ssh public key /Users/adam/.ssh/id_rsa.pub

エンターキーをおすとすぐに存在しているsshキーか新しいものをアップロードしてくれます。後でコードをプッシュするときに使います。

アプリケーションの作成

既に存在しているアプリケーションから始める人もいるかもしれませんが、もしそうでなければ、あなたに使ってもらえる簡単な"hello,world"のソースコードを用意しています :

web.js

:::nodejs
var express = require("express");
var app = express();
app.use(express.logger());

app.get('/', function(request, response) {
  response.send('Hello World!');
});

var port = process.env.PORT || 5000;
app.listen(port, function() {
  console.log("Listening on " + port);
});

NPMでの依存ファイルの宣言

Herokuはpackage.jsonの存在によって、アプリがNode.jsの物である事を認識します。たとえあなたのアプリケーションが何の依存ファイルも持っていなくても、Nodeのアプリケーションだと示すために、名前とバージョン、空の依存ファイルを宣言するpackage.jsonを作る必要があります。

ここに上で作ったExpressアプリケーションのためのpackage.jsonの例を示します :

package.json

:::nodejs
{
  "name": "node-example",
  "version": "0.0.1",
  "dependencies": {
    "express": "3.1.x"
  },
  "engines": {
    "node": "0.10.x",
    "npm": "1.2.x"
  }
}

それでは、ローカルで依存ファイルをインストールするために、npmを使ってみましょう :

Nodeの[ベストプラクティス](http://www.futurealoof.com/posts/nodemodules-in-git.html)として、デプロイを早くするため、また[開発と本番の環境を揃えるため](http://www.12factor.net/dev-prod-parity)に、ソースのリポジトリ内に`node_modules`ディレクトリを含める事があります。
:::term
$ npm install

全てのあなたのアプリケーションの依存ファイルはpackage.jsonの中で宣言され、いかなるシステムレベルのパッケージに頼らないように注意してください。

Procfileへのプロセスタイプの宣言

アプリケーションのルートディレクトリにあるテキストファイルであるProcfileを使って、Web Dynoを開始させるために何のコマンドを実行するべきかを明示的に宣言します。今回は、単純にnodeを使ってNodeのスクリプトを実行する必要があります。

これは私たちのアプリケーションのためのProcfileです :

:::term
web: node web.js

これは、1個のwebプロセスタイプと実行する必要のあるコマンドを宣言しています。"web"と付けることはここではとても重要です。これは、このプロセスタイプがHerokuのHTTPルーティングのスタックに積まれ、デプロイされた際にWebトラフィックを受け付けることを意味しています。

これでForeman を使って、ローカルでProcfileを使う事が出来るようになりました。(Toolbeltの一部としてインストールされています) :

:::term
$ foreman start
14:39:04 web.1     | started with pid 24384
14:39:04 web.1     | Listening on 5000

アプリケーションが5000番ポートで立ち上がります。curlやブラウザで適切に動いているかを確認した上で、Ctrl-Cで終了します。

Gitへのあなたのアプリケーションの格納

今、私たちはアプリの中に3つの主要な構成要素を持っています。package.jsonの中の依存関係ファイル、Procfileの中のプロセスタイプ、そしてweb.jsの中にある私たちのアプリのソースです。Gitに追加していきましょう :

:::term
$ git init
$ git add .
$ git commit -m "init"

Herokuへのアプリケーションのデプロイ

(Herokuの)アプリケーションを作成します :

:::term
$ heroku create
Creating sharp-rain-871... done, stack is cedar
http://sharp-rain-871.herokuapp.com/ | [email protected]:sharp-rain-871.git
Git remote heroku added

コードをデプロイします :

:::term
$ git push heroku master
Counting objects: 343, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (224/224), done.
Writing objects: 100% (250/250), 238.01 KiB, done.
Total 250 (delta 63), reused 0 (delta 0)

-----> Node.js app detected
-----> Resolving engine versions
       Using Node.js version: 0.10.3
       Using npm version: 1.2.18
-----> Fetching Node.js binaries
-----> Vendoring node into slug
-----> Installing dependencies with npm
       ....
       Dependencies installed
-----> Building runtime environment
-----> Discovering process types
       Procfile declares types -> web

-----> Compiled slug size: 4.1MB
-----> Launching... done, v9
       http://sharp-rain-871.herokuapp.com deployed to Heroku

To [email protected]:sharp-rain-871.git
 * [new branch]      master -> master

アプリケーションへの訪問

Herokuにコードをデプロイしました、そしてProcfileの中にプロセスタイプを指定しました。今、あなたはHerokuに対してプロセスタイプを実行するための指示を出す事が出来ます。Herokuはdynoに関連づいたコマンドを実行することでこれを行います。dynoとはHerokuにおける基本的な構成要素の単位になっている軽量コンテナのことです。

webプロセスタイプが実行されているdynoがあることを確かめてみましょう :

:::term
$ heroku ps:scale web=1

アプリケーションのdynoの状態を確認することができます。このheroku psコマンドはあなたのアプリケーションの実行中のdynoをリストします :

:::term
$ heroku ps
=== web: `node web.js`
web.1: up for 10s

ここにdynoが一つ走っています。

heroku openを使ってブラウザでアプリを確認することができます。

:::term
$ heroku open
Opening sharp-rain-871... done

Dynoのスリープと拡張

実行中のWeb dynoを一つだけ持っている事は、dynoが非アクティブになったあと1時間経つとスリープすることを意味します。これは再度立ち上がるときの最初のリクエストに対して数秒の遅れが発生することを意味します。後続のリクエストは通常通りに帰ってくるでしょう。

これを避けるために、web dynoを1個以上に増やすことが出来ます。例えば :

:::term
$ heroku ps:scale web=2

それぞれのアプリケーションごとに、Herokuは750時間のdyno無料利用時間を提供しています。2個のdynoで動いているアプリケーションは、月々のこの無料利用時間を超える可能性が高いので、増やしたものを戻してみましょう :

:::term
$ heroku ps:scale web=1

ログの確認

Herokuは、アプリケーションの内容物を実行しているすべてのdynoの出力ストリームから時系列イベントのストリームとしてログを扱います。HerokuのLogplexはこれらのイベントの全てをあつかう単体のチャネルを提供しています。

ログ用コマンドの一つを使って、実行中のあなたのアプリケーションの情報を見てみましょう。heroku logs を実行します。 :

:::term
$ heroku logs
2011-03-10T10:22:30-08:00 heroku[web.1]: State changed from created to starting
2011-03-10T10:22:32-08:00 heroku[web.1]: Running process with command: `node web.js`
2011-03-10T10:22:33-08:00 heroku[web.1]: Listening on 18320
2011-03-10T10:22:34-08:00 heroku[web.1]: State changed from starting to up

NODE_ENVの設定

Expressフレームワークはキャッシュに関するいくつかの振る舞いを決めるためにNODE_ENV環境変数を使用します。もしExpressを使っているようであれば、この値を設定変数として設定する必要があります :

:::term
$ heroku config:set NODE_ENV=production
Adding config vars:
  NODE_ENV => production
Restarting app... done, v3.

コンソール

Herokuでは、必要な時にスクリプトとそのためだけに実行されるアプリケーションであるone-off dynoの中で、heroku runを使って、コマンドを実行することが可能です。 あなたのアプリケーションの環境の中で実験のために、ローカルのターミナルでREPLプロセスを実行するためにこれを使います。

:::term
$ heroku run node
Running `node` attached to terminal... up, ps.1
>

このコンソールではNode.jsの標準ライブラリ以外は何もロードされていません。ここからrequireを使ってあなたのアプリケーションのいくつかのファイルを要求することができます。

一歩進んだHTTPの機能

CedarスタックではまだWebソケットのプロトコルはサポートされていません。

herokuapp.comのサブドメイン上にあるCedarアプリケーションで利用可能なHTTPスタックはHTTP1.1, ロングポーリング、チャンクドレスポンスをサポートしています。

ワーカーの実行

Procfileのフォーマットでは、異なったプロセスタイプをいくつでも実行することができます。例えば、あなたのWebプロセスを補助するWorkerプロセスがほしいと宣言してみましょう :

Procfile

web: node web.js
worker: node worker.js
拡張のために1個以上のDynoを動かす事で、あなたのアカウントの変更が必要になるでしょう. [Dynoの費用](usage-and-billing)について更に調べてみてください。

この変更をHerokuにPushし、Workerを起動します :

:::term
$ heroku ps:scale worker=1
Scaling worker processes... done, now running 1

PostgreSQLデータベースの使用

あなたのアプリケーションに無料のHeroku-Postgresスターターティア開発データベースを追加するために、以下のコマンドを実行してください :

:::term
$ heroku addons:add heroku-postgresql:dev
Adding heroku-postgresql:dev... done, v3 (free)

これでDATABASE_URL環境変数を設定します。NPMモジュールのpgを依存ファイル郡に追加してください :

:::json
"dependencies": {
  "pg": "2.x",
  "express": "3.x"
}

そして、あなたのコードのどこかからDATABASE_URLと接続するためにモジュールを使用してください :

:::javascript
var pg = require('pg');

pg.connect(process.env.DATABASE_URL, function(err, client, done) {
  client.query('SELECT * FROM your_table', function(err, result) {
    done();
    if(err) return console.error(err);
    console.log(result.rows);
  });
});

HerokuとPostgreSQLについてはこちらで更に詳しく確認できます。

MongoDBの使用

あなたのアプリケーションにMongoDBのデータベースを追加するために、MongoDBのアドオンの中から1つ選んで追加してください :

:::term
$ heroku addons:add mongolab

依存ファイル群に、NPMモジュールのmongodbを追加してください :

:::json
"dependencies": {
  ...
  "mongodb" : "1.1.11"
  }

モジュールを使ってその環境に配備されている、追加されたMongoDBのURLを使うために接続をしてください :

:::javascript
var mongo = require('mongodb');

var mongoUri = process.env.MONGOLAB_URI ||
  process.env.MONGOHQ_URL ||
  'mongodb://localhost/mydb';

mongo.Db.connect(mongoUri, function (err, db) {
  db.collection('mydocs', function(er, collection) {
    collection.insert({'mykey': 'myvalue'}, {safe: true}, function(er,rs) {
    });
  });
});

Redisの使用

あなたのアプリケーションにRedisのデータベースを追加するために、このコマンドを実行してください :

:::term
$ heroku addons:add redistogo

これはREDISTOGO_URL環境変数を設定します。NPMモジュールのredis-urlをあなたの依存ファイル群に追加してください :

:::nodejs
"dependencies": {
  ...
  "redis-url": "0.1.0"
}

モジュールを使って、あなたのコードのどこかから、REDISTOGO_URLと接続をしてください :

:::nodejs
var redis = require('redis-url').connect(process.env.REDISTOGO_URL);

redis.set('foo', 'bar');

redis.get('foo', function(err, value) {
  console.log('foo is: ' + value);
});

トラブルシューティング

もし、アプリケーションをプッシュしたらそれがクラッシュしてしまった場合(heroku pscrashedと表示される)、何が行けなかったのかを見つけるために、ログを確認してください。ここにはいくつかの一般的な問題がでてきます。

依存ファイルの欠如

もし、依存ファイルがないことでクラッシュしているならば、ただローカルにインストールしただけで、あなたのpackage.jsonに書かれていない可能性があります。

次のステップ

  • Node.jsアプリケーションの開発とデプロイについて更に学ぶためにNode.jsのカテゴリへ訪問する。
  • アプリケーションを書いたり、構成したり、デプロイしたり、実行する時に直面するだろう概念について、技術的な大枠を知りたい場合にHerokuの仕組みを読む。
Clone this wiki locally