-
Notifications
You must be signed in to change notification settings - Fork 9
Nodejs
このチュートリアルはHerokuにデプロイされるNode.jsとExpressウェブフレームワークについて扱って行きます。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"のソースコードを用意しています :
:::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);
});
Herokuはpackage.json
の存在によって、アプリがNode.jsの物である事を認識します。たとえあなたのアプリケーションが何の依存ファイルも持っていなくても、Nodeのアプリケーションだと示すために、名前とバージョン、空の依存ファイルを宣言するpackage.json
を作る必要があります。
ここに上で作ったExpressアプリケーションのための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
を使ってみましょう :
:::term
$ npm install
全てのあなたのアプリケーションの依存ファイルはpackage.json
の中で宣言され、いかなるシステムレベルのパッケージに頼らないように注意してください。
アプリケーションのルートディレクトリにあるテキストファイルである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で終了します。
今、私たちはアプリの中に3つの主要な構成要素を持っています。package.json
の中の依存関係ファイル、Procfile
の中のプロセスタイプ、そしてweb.js
の中にある私たちのアプリのソースです。Gitに追加していきましょう :
:::term
$ git init
$ git add .
$ git commit -m "init"
(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
実行中の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
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
を使ってあなたのアプリケーションのいくつかのファイルを要求することができます。
herokuapp.com
のサブドメイン上にあるCedarアプリケーションで利用可能なHTTPスタックはHTTP1.1, ロングポーリング、チャンクドレスポンスをサポートしています。
Procfile
のフォーマットでは、異なったプロセスタイプをいくつでも実行することができます。例えば、あなたのWebプロセスを補助するWorkerプロセスがほしいと宣言してみましょう :
web: node web.js
worker: node worker.js
この変更をHerokuにPushし、Workerを起動します :
:::term
$ heroku ps:scale worker=1
Scaling worker processes... done, now running 1
あなたのアプリケーションに無料の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のアドオンの中から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のデータベースを追加するために、このコマンドを実行してください :
:::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 ps
でcrashed
と表示される)、何が行けなかったのかを見つけるために、ログを確認してください。ここにはいくつかの一般的な問題がでてきます。
もし、依存ファイルがないことでクラッシュしているならば、ただローカルにインストールしただけで、あなたのpackage.json
に書かれていない可能性があります。
- Node.jsアプリケーションの開発とデプロイについて更に学ぶためにNode.jsのカテゴリへ訪問する。
- アプリケーションを書いたり、構成したり、デプロイしたり、実行する時に直面するだろう概念について、技術的な大枠を知りたい場合にHerokuの仕組みを読む。