Posted at

Cloud Foundry(v2)を使ったDevHubのデプロイ

More than 5 years have passed since last update.


Cloud Foundry(v2)を使ったDevHubのデプロイ

普段はCloud Foundry関係の仕事を担当しています。

まだまだ『Cloud Foundry』の日本語の情報が少なく、アプリケーション開発者の方に

『Cloud Foundry』というをPaaSがどのようなものかを知って頂く必要があると思っていますので

まずは世の中に公開されている個人的に便利だなと思うアプリを例に

どのようにしてCloud Foundryに載せていくのかを紹介していきたいと思っています。

本記事では、つい先日オープンβが開始され無料でCloud Foundry v2環境を利用可能な

IBMさんのサービスBlueMixを使ってDevHubをデプロイしていく流れを通して

Cloud Foundryのv2環境を利用していきたいと思います。


Cloud Foundryとは

Cloud FoundryとPivotal社(以前はVMware社)のPaaS基盤です。

内部的は主にRubyで実装されており、最近ではより性能向上を図る為にGo言語で実装されているコンポーネントも多くなって来ました。

ソースは全てGitHub上で公開されており、内部実装がどのようになっているかというのが確認することが出来るので自分のPC上でCloud Foundryを構築する事も可能となっています。

また、他のPaaSとして有名なherokuで利用されている、『buildpack』と呼ばれる仕組みをCloud Foundryのv2では取り入れられており、heroku向けに動くように公開されているアプリケーションが比較的簡単にCloud Foundry上でも動作させることが可能とってきました。


DevHubとは

プログラマ向けのコミュニケーションツールで、node.jsで実装されており内部的にはwebsocketを使ったIRCのようなwebアプリのツールです

https://github.com/volpe28v/DevHub


BlueMixへの登録


まずはBlueMixのOpenβを利用するにあたりIBM IDの登録を行います



  1. BlueMixのサイトページの『Join us in beta』をクリックします

  2. 画面下の『Don't have an IBM ID? Register』をクリックします

  3. 「IBM ID 登録」画面でIBM ID(メールアドレス)とパスワードを決めます。
    ※こちらのIDとパスワードは後ほどCloud Foundryにログインする際に利用します

  4. 必須項目を入力し『次へ進む』をクリックします。

  5. 「ユーザ情報」の入力画面で必須項目を埋め『送信』をクリックします

  6. 登録完了のページが表示されたら再度BlueMixサイトページの『Join us in beta』をクリックします

  7. 「SECURE ACCESS CODE」の画面で先ほど登録したIBM IDのメールアドレスに届いたアクセスコードを入力し、『submit』をクリックします

  8. 「TERMS AND CONDITIONS 」の画面で『Why are you interested in the beta?』の質問に解答し、『I Accept』をチェックした後『SUBMIT』ボタンをクリックし、登録完了です。

  9. およそ1時間程すると登録したメールアドレスに登録完了のメールが届きます。


Cloud Foundry用のクライアントの準備

今回はCloud Foundryを利用したPaaSの特徴である

「基本操作部分は互換性を持っている」 という事を表す為

BlueMixへの操作はCloud Foundry公式で公開されているGo言語で実装された『cfコマンド』と呼ばれるクライアントを利用していきます。


cfコマンドのダウンロードページから自分の環境に合わせたバイナリファイルをダウンロードします。

※今回はUbuntu 12.04 LTS 64bit環境での手順を説明していきますのでLinux 64 bit binaryをダウンロードします

ダウンロード

$ wget https://github.com/cloudfoundry/cli/releases/download/v6.0.1/cf-linux-amd64.tgz

解凍

$ tar zxfv cf-linux-amd64.tgz

PATHの通った場所等にcfコマンドを移動

$ sudo mv cf /usr/local/bin

またはexportでPATHを通します

$ export PATH=$PWD:$PATH

version確認

$ cf -v

cf version 6.0.1-9df4861

バージョンが表示されましたら準備は完了となります。


DevHubのソースを準備

$ git clone https://github.com/volpe28v/DevHub.git

$ cd DevHub


BlueMixにcfコマンドからログイン

$ cf login -a https://api.ng.bluemix.net -u 'ibm idに登録したメールアドレス' -p 'ibm idに登録したパスワード'

API endpoint: https://api.ng.bluemix.net
Authenticating...
OK

Targeted org hogehoge@hogehoge.com

Targeted space dev

API endpoint: https://api.ng.bluemix.net (API version: 2.0.0)
User: hogehoge@hogehoge.com
Org: hogehoge@hogehoge.com
Space: dev


DevHubのpush(デプロイ)

※pushとはcfコマンドを使ってCloud Foundry環境へのアプリを展開することを意味します。

また、以後の『cf-devhub』部分はそれぞれの任意の名称に変更した形で読み替えてください

先ほどgit cloneしたDevHubのディレクトリの中で以下を実行します

$ cf push cf-devhub -i 1 -m 256m -c 'node app

.js -p $PORT -d devhub_db -t title' -b https://github.com/heroku/heroku-buildpac
k-nodejs.git

Creating app cf-devhub in org hogehoge@hogehoge.com / space dev as hogehoge@hogehoge.com...
OK

Creating route cf-devhub.ng.bluemix.net...
OK

Binding cf-devhub.ng.bluemix.net to cf-devhub...
OK

Uploading cf-devhub...
Uploading from: /tmp/bluemix/DevHub
341.4K, 69 files
OK

Starting app cf-devhub in org hogehoge@hogehoge.com / space dev as hogehoge@hogehoge.com...
-----> Downloaded app package (1.6M)
OK
Initialized empty Git repository in /tmp/buildpacks/heroku-buildpack-nodejs/.git/
-----> Requested node range: 0.9.6
-----> Resolved node version: 0.9.6
-----> Downloading and installing node
-----> Installing dependencies
npm http GET https://registry.npmjs.org/socket.io/0.9.16
npm http GET https://registry.npmjs.org/express/3.4.8
npm http GET https://registry.npmjs.org/commander
npm http GET https://registry.npmjs.org/ejs/0.8.5
npm http GET https://registry.npmjs.org/mongodb/0.9.8
npm http GET https://registry.npmjs.org/request
npm http 200 https://registry.npmjs.org/commander
npm http GET https://registry.npmjs.org/commander/-/commander-0.5.2.tgz
npm http 200 https://registry.npmjs.org/request
npm http 200 https://registry.npmjs.org/commander/-/commander-0.5.2.tgz
npm http 200 https://registry.npmjs.org/express/3.4.8
npm http GET https://registry.npmjs.org/request/-/request-2.34.0.tgz
npm http 200 https://registry.npmjs.org/ejs/0.8.5
npm http GET https://registry.npmjs.org/express/-/express-3.4.8.tgz
npm http 200 https://registry.npmjs.org/socket.io/0.9.16
npm http GET https://registry.npmjs.org/ejs/-/ejs-0.8.5.tgz
npm http GET https://registry.npmjs.org/socket.io/-/socket.io-0.9.16.tgz
npm http 200 https://registry.npmjs.org/express/-/express-3.4.8.tgz
npm http 200 https://registry.npmjs.org/mongodb/0.9.8
npm http GET https://registry.npmjs.org/mongodb/-/mongodb-0.9.8.tgz
npm http 200 https://registry.npmjs.org/request/-/request-2.34.0.tgz
npm http 200 https://registry.npmjs.org/socket.io/-/socket.io-0.9.16.tgz
npm http 200 https://registry.npmjs.org/ejs/-/ejs-0.8.5.tgz
npm http 200 https://registry.npmjs.org/mongodb/-/mongodb-0.9.8.tgz
npm http GET https://registry.npmjs.org/forever-agent
npm http GET https://registry.npmjs.org/node-uuid
npm http GET https://registry.npmjs.org/mime
npm http GET https://registry.npmjs.org/tough-cookie
npm http GET https://registry.npmjs.org/form-data
npm http GET https://registry.npmjs.org/tunnel-agent
npm http GET https://registry.npmjs.org/http-signature
npm http GET https://registry.npmjs.org/oauth-sign
npm http GET https://registry.npmjs.org/hawk
npm http GET https://registry.npmjs.org/aws-sign2
npm http GET https://registry.npmjs.org/qs
npm http GET https://registry.npmjs.org/json-stringify-safe
npm http GET https://registry.npmjs.org/range-parser/0.0.4
npm http GET https://registry.npmjs.org/mkdirp/0.3.5
npm http GET https://registry.npmjs.org/cookie/0.1.0
npm http GET https://registry.npmjs.org/buffer-crc32/0.2.1
npm http GET https://registry.npmjs.org/fresh/0.2.0
npm http GET https://registry.npmjs.org/methods/0.1.0
npm http GET https://registry.npmjs.org/send/0.1.4
npm http GET https://registry.npmjs.org/cookie-signature/1.0.1
npm http GET https://registry.npmjs.org/merge-descriptors/0.0.1
npm http GET https://registry.npmjs.org/debug
npm http GET https://registry.npmjs.org/connect/2.12.0
npm http GET https://registry.npmjs.org/commander/1.3.2
npm http 200 https://registry.npmjs.org/node-uuid
npm http GET https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.1.tgz
npm http 200 https://registry.npmjs.org/tunnel-agent
npm http GET https://registry.npmjs.org/base64id/0.1.0
npm http GET https://registry.npmjs.org/redis/0.7.3
npm http GET https://registry.npmjs.org/socket.io-client/0.9.16
npm http GET https://registry.npmjs.org/policyfile/0.0.4
npm http GET https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.3.0.tgz
npm http 200 https://registry.npmjs.org/http-signature
npm http 200 https://registry.npmjs.org/forever-agent
npm http 200 https://registry.npmjs.org/mime
npm http GET https://registry.npmjs.org/http-signature/-/http-signature-0.10.0.tgz
npm http 200 https://registry.npmjs.org/oauth-sign
npm http GET https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz
npm http GET https://registry.npmjs.org/mime/-/mime-1.2.11.tgz
npm http GET https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.3.0.tgz
npm http 200 https://registry.npmjs.org/aws-sign2
npm http GET https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz
npm http 200 https://registry.npmjs.org/form-data
npm http GET https://registry.npmjs.org/form-data/-/form-data-0.1.2.tgz
npm http 200 https://registry.npmjs.org/json-stringify-safe
npm http GET https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.0.tgz
npm http 200 https://registry.npmjs.org/qs
npm http GET https://registry.npmjs.org/qs/-/qs-0.6.6.tgz
npm http 200 https://registry.npmjs.org/range-parser/0.0.4
npm http GET https://registry.npmjs.org/range-parser/-/range-parser-0.0.4.tgz
npm http 200 https://registry.npmjs.org/cookie/0.1.0
npm http GET https://registry.npmjs.org/cookie/-/cookie-0.1.0.tgz
npm http 200 https://registry.npmjs.org/mkdirp/0.3.5
npm http GET https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz
npm http 200 https://registry.npmjs.org/buffer-crc32/0.2.1
npm http GET https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz
npm http 200 https://registry.npmjs.org/fresh/0.2.0
npm http GET https://registry.npmjs.org/fresh/-/fresh-0.2.0.tgz
npm http 200 https://registry.npmjs.org/methods/0.1.0
npm http GET https://registry.npmjs.org/methods/-/methods-0.1.0.tgz
npm http 200 https://registry.npmjs.org/cookie-signature/1.0.1
npm http 200 https://registry.npmjs.org/send/0.1.4
npm http 200 https://registry.npmjs.org/tough-cookie
npm http GET https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.1.tgz
npm http GET https://registry.npmjs.org/tough-cookie/-/tough-cookie-0.12.1.tgz
npm http GET https://registry.npmjs.org/send/-/send-0.1.4.tgz
npm http 200 https://registry.npmjs.org/merge-descriptors/0.0.1
npm http GET https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-0.0.1.tgz
npm http 200 https://registry.npmjs.org/debug
npm http GET https://registry.npmjs.org/debug/-/debug-0.7.4.tgz
npm http 200 https://registry.npmjs.org/commander/1.3.2
npm http 200 https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.1.tgz
npm http 200 https://registry.npmjs.org/connect/2.12.0
npm http GET https://registry.npmjs.org/commander/-/commander-1.3.2.tgz
npm http 200 https://registry.npmjs.org/base64id/0.1.0
npm http 200 https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.3.0.tgz
npm http GET https://registry.npmjs.org/connect/-/connect-2.12.0.tgz
npm http 200 https://registry.npmjs.org/http-signature/-/http-signature-0.10.0.tgz
npm http 200 https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz
npm http 200 https://registry.npmjs.org/mime/-/mime-1.2.11.tgz
npm http GET https://registry.npmjs.org/base64id/-/base64id-0.1.0.tgz
npm http 200 https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.3.0.tgz
npm http 200 https://registry.npmjs.org/redis/0.7.3
npm http 200 https://registry.npmjs.org/policyfile/0.0.4
npm http GET https://registry.npmjs.org/redis/-/redis-0.7.3.tgz
npm http 200 https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz
npm http GET https://registry.npmjs.org/policyfile/-/policyfile-0.0.4.tgz
npm http 200 https://registry.npmjs.org/qs/-/qs-0.6.6.tgz
npm http 200 https://registry.npmjs.org/range-parser/-/range-parser-0.0.4.tgz
npm http 200 https://registry.npmjs.org/cookie/-/cookie-0.1.0.tgz
npm http 200 https://registry.npmjs.org/form-data/-/form-data-0.1.2.tgz
npm http 200 https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz
npm http 200 https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.0.tgz
npm http 200 https://registry.npmjs.org/fresh/-/fresh-0.2.0.tgz
npm http 200 https://registry.npmjs.org/socket.io-client/0.9.16
npm http 200 https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.1.tgz
npm http 200 https://registry.npmjs.org/send/-/send-0.1.4.tgz
npm http 200 https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-0.0.1.tgz
npm http 200 https://registry.npmjs.org/methods/-/methods-0.1.0.tgz
npm http 200 https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz
npm http 200 https://registry.npmjs.org/tough-cookie/-/tough-cookie-0.12.1.tgz
npm http GET https://registry.npmjs.org/socket.io-client/-/socket.io-client-0.9.16.tgz
npm http 200 https://registry.npmjs.org/commander/-/commander-1.3.2.tgz
npm http 200 https://registry.npmjs.org/connect/-/connect-2.12.0.tgz
npm http 200 https://registry.npmjs.org/debug/-/debug-0.7.4.tgz
npm http 200 https://registry.npmjs.org/redis/-/redis-0.7.3.tgz
npm http 200 https://registry.npmjs.org/base64id/-/base64id-0.1.0.tgz
npm http 200 https://registry.npmjs.org/policyfile/-/policyfile-0.0.4.tgz
npm http 200 https://registry.npmjs.org/socket.io-client/-/socket.io-client-0.9.16.tgz
npm http 200 https://registry.npmjs.org/hawk
npm http GET https://registry.npmjs.org/hawk/-/hawk-1.0.0.tgz
npm http 200 https://registry.npmjs.org/hawk/-/hawk-1.0.0.tgz
npm http GET https://registry.npmjs.org/combined-stream
npm http GET https://registry.npmjs.org/async

> mongodb@0.9.8 install /tmp/staged/app/node_modules/mongodb
> node install.js

npm http GET https://registry.npmjs.org/ctype/0.5.2
npm http GET https://registry.npmjs.org/assert-plus/0.1.2
npm http GET https://registry.npmjs.org/asn1/0.1.11
npm http 200 https://registry.npmjs.org/asn1/0.1.11
================================================================================
= =
= To install with C++ bson parser do <npm install mongodb --mongodb:native> =
= =
================================================================================
npm http GET https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz
npm http 200 https://registry.npmjs.org/combined-stream
npm http GET https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.4.tgz
npm http 200 https://registry.npmjs.org/async
npm http GET https://registry.npmjs.org/async/-/async-0.2.10.tgz
npm http 200 https://registry.npmjs.org/ctype/0.5.2
npm http 200 https://registry.npmjs.org/assert-plus/0.1.2
npm http GET https://registry.npmjs.org/ctype/-/ctype-0.5.2.tgz
npm http GET https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.2.tgz
npm http 200 https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz
npm http 200 https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.4.tgz
npm http GET https://registry.npmjs.org/punycode
npm http 200 https://registry.npmjs.org/async/-/async-0.2.10.tgz
npm http 200 https://registry.npmjs.org/ctype/-/ctype-0.5.2.tgz
npm http 200 https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.2.tgz
npm http 200 https://registry.npmjs.org/punycode
npm http GET https://registry.npmjs.org/hoek
npm http GET https://registry.npmjs.org/boom
npm http GET https://registry.npmjs.org/cryptiles
npm http GET https://registry.npmjs.org/sntp
npm http GET https://registry.npmjs.org/punycode/-/punycode-1.2.4.tgz
npm http 200 https://registry.npmjs.org/hoek
npm http 200 https://registry.npmjs.org/sntp
npm http GET https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz
npm http GET https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz
npm http 200 https://registry.npmjs.org/punycode/-/punycode-1.2.4.tgz
npm http 200 https://registry.npmjs.org/cryptiles
npm http 200 https://registry.npmjs.org/boom
npm http GET https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz
npm http GET https://registry.npmjs.org/boom/-/boom-0.4.2.tgz
npm http 200 https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz
npm http 200 https://registry.npmjs.org/boom/-/boom-0.4.2.tgz
npm http 200 https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz
npm http 200 https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz
npm http GET https://registry.npmjs.org/mime
npm http GET https://registry.npmjs.org/keypress
npm http 304 https://registry.npmjs.org/mime
npm http 200 https://registry.npmjs.org/keypress
npm http GET https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz
npm http 200 https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz
npm http GET https://registry.npmjs.org/delayed-stream/0.0.5
npm http 200 https://registry.npmjs.org/delayed-stream/0.0.5
npm http GET https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz
npm http GET https://registry.npmjs.org/batch/0.5.0
npm http GET https://registry.npmjs.org/qs/0.6.6
npm http GET https://registry.npmjs.org/bytes/0.2.1
npm http GET https://registry.npmjs.org/pause/0.0.1
npm http GET https://registry.npmjs.org/uid2/0.0.3
npm http GET https://registry.npmjs.org/raw-body/1.1.2
npm http GET https://registry.npmjs.org/negotiator/0.3.0
npm http GET https://registry.npmjs.org/multiparty/2.2.0
npm http 200 https://registry.npmjs.org/qs/0.6.6
npm http 200 https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz
npm http 200 https://registry.npmjs.org/uid2/0.0.3
npm http 200 https://registry.npmjs.org/negotiator/0.3.0
npm http GET https://registry.npmjs.org/qs/-/qs-0.6.6.tgz
npm http 200 https://registry.npmjs.org/multiparty/2.2.0
npm http 200 https://registry.npmjs.org/qs/-/qs-0.6.6.tgz
npm http GET https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz
npm http GET https://registry.npmjs.org/negotiator/-/negotiator-0.3.0.tgz
npm http GET https://registry.npmjs.org/multiparty/-/multiparty-2.2.0.tgz
npm http 200 https://registry.npmjs.org/raw-body/1.1.2
npm http GET https://registry.npmjs.org/raw-body/-/raw-body-1.1.2.tgz
npm http 200 https://registry.npmjs.org/negotiator/-/negotiator-0.3.0.tgz
npm http 200 https://registry.npmjs.org/multiparty/-/multiparty-2.2.0.tgz
npm http 200 https://registry.npmjs.org/batch/0.5.0
npm http 200 https://registry.npmjs.org/pause/0.0.1
npm http GET https://registry.npmjs.org/batch/-/batch-0.5.0.tgz
npm http GET https://registry.npmjs.org/pause/-/pause-0.0.1.tgz
npm http 200 https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz
npm http 200 https://registry.npmjs.org/raw-body/-/raw-body-1.1.2.tgz
npm http 200 https://registry.npmjs.org/pause/-/pause-0.0.1.tgz
npm http 200 https://registry.npmjs.org/bytes/0.2.1
npm WARN package.json uid2@0.0.3 No README.md file found!
npm http GET https://registry.npmjs.org/bytes/-/bytes-0.2.1.tgz
npm http 200 https://registry.npmjs.org/batch/-/batch-0.5.0.tgz
npm http 200 https://registry.npmjs.org/bytes/-/bytes-0.2.1.tgz
npm http GET https://registry.npmjs.org/xmlhttprequest/1.4.2
npm http GET https://registry.npmjs.org/active-x-obfuscator/0.0.1
npm http GET https://registry.npmjs.org/uglify-js/1.2.5
npm http GET https://registry.npmjs.org/ws
npm http 200 https://registry.npmjs.org/ws
npm http GET https://registry.npmjs.org/ws/-/ws-0.4.31.tgz
npm http 200 https://registry.npmjs.org/xmlhttprequest/1.4.2
npm http 200 https://registry.npmjs.org/uglify-js/1.2.5
npm http GET https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.4.2.tgz
npm http 200 https://registry.npmjs.org/active-x-obfuscator/0.0.1
npm http GET https://registry.npmjs.org/uglify-js/-/uglify-js-1.2.5.tgz
npm http GET https://registry.npmjs.org/active-x-obfuscator/-/active-x-obfuscator-0.0.1.tgz
npm http 200 https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.4.2.tgz
npm http 200 https://registry.npmjs.org/uglify-js/-/uglify-js-1.2.5.tgz
npm http 200 https://registry.npmjs.org/ws/-/ws-0.4.31.tgz
npm http 200 https://registry.npmjs.org/active-x-obfuscator/-/active-x-obfuscator-0.0.1.tgz
npm http GET https://registry.npmjs.org/zeparser/0.0.5
npm http 200 https://registry.npmjs.org/zeparser/0.0.5
npm http GET https://registry.npmjs.org/zeparser/-/zeparser-0.0.5.tgz
npm http GET https://registry.npmjs.org/nan
npm http GET https://registry.npmjs.org/tinycolor
npm http GET https://registry.npmjs.org/options
npm http GET https://registry.npmjs.org/commander
npm http 200 https://registry.npmjs.org/tinycolor
npm http GET https://registry.npmjs.org/tinycolor/-/tinycolor-0.0.1.tgz
npm http 200 https://registry.npmjs.org/zeparser/-/zeparser-0.0.5.tgz
npm http 304 https://registry.npmjs.org/commander
npm http GET https://registry.npmjs.org/commander/-/commander-0.6.1.tgz
npm http 200 https://registry.npmjs.org/options
npm http GET https://registry.npmjs.org/options/-/options-0.0.5.tgz
npm http 200 https://registry.npmjs.org/tinycolor/-/tinycolor-0.0.1.tgz
npm http 200 https://registry.npmjs.org/commander/-/commander-0.6.1.tgz
npm http 200 https://registry.npmjs.org/options/-/options-0.0.5.tgz
npm http 200 https://registry.npmjs.org/nan
npm http GET https://registry.npmjs.org/nan/-/nan-0.3.2.tgz
npm http 200 https://registry.npmjs.org/nan/-/nan-0.3.2.tgz
npm http GET https://registry.npmjs.org/readable-stream
npm http GET https://registry.npmjs.org/stream-counter
npm http 200 https://registry.npmjs.org/readable-stream
npm http GET https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.11.tgz

> ws@0.4.31 install /tmp/staged/app/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws
> (node-gyp rebuild 2> builderror.log) || (exit 0)

npm http 200 https://registry.npmjs.org/stream-counter
npm http GET https://registry.npmjs.org/stream-counter/-/stream-counter-0.2.0.tgz
npm http 200 https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.11.tgz
npm http 200 https://registry.npmjs.org/stream-counter/-/stream-counter-0.2.0.tgz
npm http GET https://registry.npmjs.org/core-util-is
npm http GET https://registry.npmjs.org/string_decoder
npm http GET https://registry.npmjs.org/debuglog/0.0.2
npm http 200 https://registry.npmjs.org/core-util-is
npm http GET https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz
npm http 200 https://registry.npmjs.org/string_decoder
npm http GET https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.25-1.tgz
npm http 200 https://registry.npmjs.org/debuglog/0.0.2
npm http GET https://registry.npmjs.org/debuglog/-/debuglog-0.0.2.tgz
npm http 200 https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz
npm http 200 https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.25-1.tgz
npm http 200 https://registry.npmjs.org/debuglog/-/debuglog-0.0.2.tgz
make: Entering directory `/tmp/staged/app/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build'
CXX(target) Release/obj.target/bufferutil/src/bufferutil.o
SOLINK_MODULE(target) Release/obj.target/bufferutil.node
SOLINK_MODULE(target) Release/obj.target/bufferutil.node: Finished
COPY Release/bufferutil.node
CXX(target) Release/obj.target/validation/src/validation.o
SOLINK_MODULE(target) Release/obj.target/validation.node
SOLINK_MODULE(target) Release/obj.target/validation.node: Finished
COPY Release/validation.node
make: Leaving directory `/tmp/staged/app/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build'
commander@0.5.2 node_modules/commander

ejs@0.8.5 node_modules/ejs

mongodb@0.9.8 node_modules/mongodb

request@2.34.0 node_modules/request
tqq json-stringify-safe@5.0.0
tqq forever-agent@0.5.2
tqq aws-sign2@0.5.0
tqq qs@0.6.6
tqq tunnel-agent@0.3.0
tqq oauth-sign@0.3.0
tqq node-uuid@1.4.1
tqq mime@1.2.11
tqq tough-cookie@0.12.1 (punycode@1.2.4)
tqq hawk@1.0.0 (cryptiles@0.2.2, sntp@0.2.4, boom@0.4.2, hoek@0.9.1)
tqq form-data@0.1.2 (async@0.2.10, combined-stream@0.0.4)
mqq http-signature@0.10.0 (assert-plus@0.1.2, asn1@0.1.11, ctype@0.5.2)

express@3.4.8 node_modules/express
tqq methods@0.1.0
tqq merge-descriptors@0.0.1
tqq range-parser@0.0.4
tqq cookie-signature@1.0.1
tqq fresh@0.2.0
tqq debug@0.7.4
tqq buffer-crc32@0.2.1
tqq cookie@0.1.0
tqq mkdirp@0.3.5
tqq send@0.1.4 (mime@1.2.11)
tqq commander@1.3.2 (keypress@0.1.0)
mqq connect@2.12.0 (uid2@0.0.3, pause@0.0.1, qs@0.6.6, bytes@0.2.1, raw-body@1.1.2, batch@0.5.0, negotiator@0.3.0, multiparty@2.2.0)

socket.io@0.9.16 node_modules/socket.io
tqq base64id@0.1.0
tqq policyfile@0.0.4
tqq redis@0.7.3
mqq socket.io-client@0.9.16 (xmlhttprequest@1.4.2, uglify-js@1.2.5, active-x-obfuscator@0.0.1, ws@0.4.31)
-----> Caching node_modules directory for future builds
-----> Cleaning up node-gyp and npm artifacts
-----> Building runtime environment
-----> Uploading droplet (15M)

1 of 1 instances running

App started

Showing health and status for app cf-devhub in org hogehoge@hogehoge.com / space dev as hogehoge@hogehoge.com...
OK

requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: cf-devhub.ng.bluemix.net

state since cpu memory disk
#0 running 2014-02-28 12:29:18 AM 0.0% 16.6M of 256M 44.4M of 1G


  • pushの後の『cf-devhub』部分がアプリケーション名(任意で1つのCloud Foundry内で基本的にはユニークなもの)
    上記の場合は『cf-devhub.ng.bluemix.net』がアプリケーションのURLになります

  • -iはインスタンス数を設定(ここでは1インスタンス)

  • -mは1インスタンスあたりのメモリ割当量(ここでは256mb)

  • -cはアプリケーションを起動させる際に呼び出すコマンド

  • -bは今回はnode.jsのアプリかつheroku向けに動くように作られたアプリの為、herokuのnode.js用のbuildpackのURLを指定します。

ここで重要なのは-cの部分に-p $PORTと指定している部分で

Cloud Foundryでは各アプリケーションが起動する際に使えるPORT番号が

アプリの起動する環境の環境変数のPORTに指定されていますので、-pの後に置くことで自動的に利用可能なポートを反映するようにします。


Serviceのbind

※ServiceのbindとはCloud Foundryに置いてアプリケーションにDB等のサービスを紐付ける事を意味します

DevHubはgithubのReadmeを読むとmongodbを使っている事が分かりますので

BlueMixでも提供されているmongodbをWeb画面から追加します



  1. BlueMixの画面右上にある『LOGIN』をクリックします

  2. 「SIGN IN」画面で『IBM ID』と『パスワード』を入力します

  3. Dashboard画面で先ほどpushした『cf-devhub』部分をクリックします
    dashboard1.png

  4. 『Add new service』をクリックします
    add-new-service.png

  5. 『mongodb』をクリックします
    mongodb.png

  6. 『ADD TO APPLICATION』をクリックします
    mongodb-2.png

  7. 「Add to:」が「cf-devhub」となっていることを確認し『CREATE』をクリックします
    create-service-instance.png

  8. 正常にアプリにmongodbが紐付けられると以下の様な表示になります
    bind-mongo.png


bindしたアプリを利用するようにする


今回はあえて heroku向けのアプリをCloud Foundryに載せ替える際にどのようにして変更していくかをなぞる形で変更していきます。


以下のように『cf logs アプリ名』と入力する事でCloud Foundry上で動作するアプリの標準出力と標準エラー出力をあたかもローカルで『tail -f』するかのように確認することが可能です

$ cf logs cf-devhub

上記の状態でデプロイしたアプリのURLにブラウザでアクセスし

※今回の例ではhttps://cf-devhub.ng.bluemix.net/


『cf logs cf-devhub』のログにエラーが出力されます

2014-02-28T00:59:50.43+0900 [App/0]   OUT New Connection from 75.126.23.243:19230

2014-02-28T00:59:50.43+0900 [App/0] ERR /home/vcap/app/lib/text_log.js:141
2014-02-28T00:59:50.43+0900 [App/0] ERR db.collection(table_active_number, function(err, collection) {
2014-02-28T00:59:50.43+0900 [App/0] ERR ^
2014-02-28T00:59:50.43+0900 [App/0] ERR TypeError: Cannot call method 'collection' of null
2014-02-28T00:59:50.43+0900 [App/0] ERR at Object.module.exports.get_active_number (/home/vcap/app/lib/text_log.js:141:6)
2014-02-28T00:59:50.43+0900 [App/0] ERR at SocketNamespace.<anonymous> (/home/vcap/app/app.js:122:12)
2014-02-28T00:59:50.43+0900 [App/0] ERR at SocketNamespace.EventEmitter.emit [as $emit] (events.js:124:20)
2014-02-28T00:59:50.43+0900 [App/0] ERR at connect (/home/vcap/app/node_modules/socket.io/lib/namespace.js:292:10)
2014-02-28T00:59:50.43+0900 [App/0] ERR at /home/vcap/app/node_modules/socket.io/lib/namespace.js:308:13
2014-02-28T00:59:50.43+0900 [App/0] ERR at SocketNamespace.authorize (/home/vcap/app/node_modules/socket.io/lib/namespace.js:252:5)
2014-02-28T00:59:50.43+0900 [App/0] ERR at SocketNamespace.handlePacket (/home/vcap/app/node_modules/socket.io/lib/namespace.js:302:14)
2014-02-28T00:59:50.43+0900 [App/0] ERR at Manager.handleClient (/home/vcap/app/node_modules/socket.io/lib/manager.js:698:32)
2014-02-28T00:59:50.43+0900 [App/0] ERR at Manager.handleUpgrade (/home/vcap/app/node_modules/socket.io/lib/manager.js:618:8)
2014-02-28T00:59:50.43+0900 [App/0] ERR at Server.<anonymous> (/home/vcap/app/node_modules/socket.io/lib/manager.js:123:10)


mongodbの接続に上手く行っていないということが分かりますので

CTRL+Cで『cf logs cf-devhub』の画面を一旦止めます。


grepコマンドを使ってmongodbの文字を探してみます

$ grep "MONGO" -R ./*

./lib/mongo_builder.js: if ( process.env.MONGOLAB_URI ){
./lib/mongo_builder.js: mongo.connect(process.env.MONGOLAB_URI, {}, function(error, db){

上記の場所にenvからMONGOLABのURIを取得している事が分かります。


先ほどのアクセスの際にmongodbに接続できなかった影響でアプリが異常停止している可能性がある為、一旦ブラウザのcf-devhubの画面を閉じた後、以下のコマンドでアプリを再起動させます。

$ cf restart cf-devhub


『cf files cf-devhub logs/env.log』にてアプリに割り当てられている環境変数を確認します。

Cloud Foundryではfilesで参照可能なlogs/配下に以下の情報が格納されています


  • env.log (割り当てられている環境変数の値が格納されています)

  • staging_task.log (buildpackを使ってアプリがCloud Foundryに展開される際のログが格納)

  • stderr.log (アプリの出力した標準エラー出力が格納)

  • stdout.log (アプリの出力した標準出力)

cf files cf-devhub logs/env.logの結果のうちVCAP_SERVICESのurl:の部分をメモします





url":"mongodb://fbd83aba-a81a-47e2-a862-71f09e9b13f1:5cfb9984-1d20-4748-8d5d-04a2124430fe@75.126.37.69:10192/db


再度『cf push』にて値を変更

先ほどメモをした『mongodb:』で始まる部分を環境変数として与える為、

『-c 'node 』の『node』の前に以下のように記述し再度pushを実行します。

実行コマンド

$ cf push cf-devhub -i 1 -m 256m -c 'MONGOLAB_URI=mongodb://fbd83aba-a81a-47e2-a862-71f09e9b13f1:5cfb9984-1d20-4748-8d5d-04a2124430fe@75.126.37.69:10192/db node app.js -p $PORT -d devhub_db -t title' -b ht

tps://github.com/heroku/heroku-buildpack-nodejs.git

実行後のログ

Updating app cf-devhub in org hogehoge@hogehoge.com / space dev as hogehoge@hogehoge.com...

OK

Uploading cf-devhub...
Uploading from: /tmp/bluemix/DevHub
341.4K, 69 files
OK

Stopping app cf-devhub in org hogehoge@hogehoge.com / space dev as hogehoge@hogehoge.com...
OK

Starting app cf-devhub in org hogehoge@hogehoge.com / space dev as hogehoge@hogehoge.com...
-----> Downloaded app package (1.6M)
OK
-----> Downloaded app buildpack cache (8.2M)
Initialized empty Git repository in /tmp/buildpacks/heroku-buildpack-nodejs/.git/
-----> Requested node range: 0.9.6
-----> Resolved node version: 0.9.6
-----> Downloading and installing node
-----> Restoring node_modules directory from cache
-----> Pruning cached dependencies not specified in package.json
-----> Installing dependencies
-----> Caching node_modules directory for future builds
-----> Cleaning up node-gyp and npm artifacts
-----> Building runtime environment
-----> Uploading droplet (15M)

1 of 1 instances running

App started

Showing health and status for app cf-devhub in org hogehoge@hogehoge.com / space dev as hogehoge@hogehoge.com...
OK

requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: cf-devhub.ng.bluemix.net

state since cpu memory disk
#0 running 2014-02-28 01:30:13 AM 0.0% 16.8M of 256M 44.2M of 1G


再度ブラウザでアクセス

再度ブラウザで

https://cf-devhub.ng.bluemix.net/

にアクセスすることでDevHubが利用可能になります

このように一部の部分を変えるだけで

heroku向けのアプリもCloud Foundry上で動作させることが可能になるといった所が

Cloud Foundryのv2の特長となります。


まとめ


  • 今回はDevHub自体の更新を取り入れやすくする為にheroku向けのアプリをソース部分を修正せずに動作させる方法を選びました。

  • 『cf push -c』部分のコマンドのPORT割り当てやmongodbの設定を手動で行いましたが、自分で環境変数などを用いて自動的に設定するようにする事も可能です。※

  • 次回以降もGitHub上で公開されているその他の便利そうなツールをCloud Foundryに載せ替える方法を書いていく事でアプリケーション開発者の方のヒントになればと考えています。

※おそらくPORTについては設定しなくてもデフォルトの挙動で環境変数から取得しているコードがあるようです


今回BlueMix上にpushしたDevHubのアクセス情報

今回pushしたサンプルへのアクセス方法は以下の通りです。

user: cloudfoundry

pass: pass
url: https://cf-devhub.ng.bluemix.net/