Bluemixにアプリケーションをデプロイするときに、アプリケーションが起動と停止を繰り返して、最終的には起動失敗となることがあります。
こんな感じの出力ですね。
-----> Uploading droplet (8.7M)
0 of 1 instances running, 1 starting
0 of 1 instances running, 1 starting
0 of 1 instances running, 1 down
0 of 1 instances running, 1 down
0 of 1 instances running, 1 starting
0 of 1 instances running, 1 starting
0 of 1 instances running, 1 down
0 of 1 instances running, 1 down
0 of 1 instances running, 1 starting
0 of 1 instances running, 1 starting
0 of 1 instances running, 1 down
0 of 1 instances running, 1 down
0 of 1 instances running, 1 failing
FAILED
Start unsuccessful
TIP: use 'cf logs HelloWorld --recent' for more information
こんなときは、エラー出力の最後のTIPにも表示されているように、cf logs application_name --recent
コマンドを利用して、ログを確認し、どこがまずいのかをチェックします。
今回のケースは単純な入力ミスで、変数名の指定間違いでした。
2015-04-22T20:46:11.49+0900 [App/0] ERR
2015-04-22T20:46:11.49+0900 [App/0] ERR /home/vcap/app/app.js:11
2015-04-22T20:46:11.49+0900 [App/0] ERR var app = express();
2015-04-22T20:46:11.49+0900 [App/0] ERR ^
2015-04-22T20:46:11.50+0900 [App/0] ERR ReferenceError: express is not defined
2015-04-22T20:46:11.50+0900 [App/0] ERR at Object.<anonymous> (/home/vcap/app/app.js:11:11)
2015-04-22T20:46:11.50+0900 [App/0] ERR at Module._compile (module.js:456:26)
2015-04-22T20:46:11.50+0900 [App/0] ERR at Object.Module._extensions..js (module.js:474:10)
2015-04-22T20:46:11.50+0900 [App/0] ERR at Module.load (module.js:356:32)
2015-04-22T20:46:11.50+0900 [App/0] ERR at Function.Module._load (module.js:312:12)
2015-04-22T20:46:11.50+0900 [App/0] ERR at Function.Module.runMain (module.js:497:10)
2015-04-22T20:46:11.50+0900 [App/0] ERR at startup (node.js:119:16)
2015-04-22T20:46:11.50+0900 [App/0] ERR at node.js:906:3
こんな感じで、cf logs
を使ってログを確認すればよいのですが、Syntax Errorや今回の変数間違いのような単純エラーを、毎回Bluemixにアプリケーションをデプロイしてから確認するのは少し面倒です。
そんなときは、ローカル環境でテストしてからBluemixにデプロイしましょう。
「Bluemixで使用しているNode.jsと同じ実装でテストしてみたい」というのであれば、IBM developerWorksのサイトから"IBM SDK for Node.js"をダウンロードし、ローカル環境に導入するとよいでしょう。
ローカル環境でテストする際の大きな注意点は、以下の2つです。
- リクエストをListenするポート番号
- Bluemixの各サービスを使用するための接続情報(VCAP_SERVICES)の取得方法
リクエストをListenするポート番号の決定方法は、とてもシンプルです。Node.jsでサーバーを作成する際に、以下のようなコーディングにすればOKです。
var server = app.listen(process.env.PORT || 3000, function() {
console.log('Listening on port %d', server.address().port);
});
Bluemixでは、Listenに使用するために割り当てられるポート番号が、環境変数PORTにセットされます。したがって、process.env.PORT
が定義されていなければ、ローカル環境と判断し、任意のポート番号(ここでは3000番)を使うようにコーディングすれば問題ありません。
少々面倒なのが、接続情報(VCAP_SERVICES)の取得方法です。以下の方法のどちらかで対応するケースが多いかと思います。
- OSの環境変数にVCAP_SERVICESを定義する
- 設定ファイルにVCAP_SERVICESの内容を記述し、利用する
「1. OSの環境変数にVCAP_SERVICESを定義する」の方法については、developwerWorksに掲載されている"Bluemix 上で稼動する Web アプリケーション開発方法 - Node.js 編"の"3-5. ローカル PC 環境での動作確認"を参照してください。
「2. 設定ファイルにVCAP_SERVICESの内容を記述し、利用する」のコーディング例は、以下のとおりです。config/VCAP_SERVICES.jsonにVCAP_SERVICESの内容がコピーされており、その内容を参照しています。
var cradle = require('cradle');
if (typeof process.env.VCAP_SERVICES === 'undefined') {
var services = require('../config/VCAP_SERVICES.json');
} else {
services = JSON.parse(process.env.VCAP_SERVICES)
};
var credentials = services['cloudantNoSQLDB'][0].credentials;
var host = credentials.host;
var port = credentials.port;
var dbName = process.env.DB_NAME || require('../config/DB_NAME.json').DB_NAME;
var db = new (cradle.Connection)(host, port, options).database(dbName);
ちなみにですが、VCAP_SERVICESの値は、Bluemixの管理コンソールより確認でき、一括コピーのボタンも用意されています。
ダッシュボードより、VCAP_SERVICESを参照したいアプリケーションをクリックし、左側の環境変数を選択します。
右上のオレンジ枠で囲ったボタンをクリックするとクリップボードに内容がコピーされます。エクスポートボタンをクリックすると、.jsonの拡張子のファイルとしてダウンロードできます。