オープンソースのPaaSソフトウェア CloudFoundry の技術情報やイベント告知などを掲載します

2015-10-19

Rocket.Chatを Cloud Foundry で動かす

「Cloud Foundry 百日行」第81日目は、Meteor製のチャットツールRocket.Chat です。
MeteorとはNodeJSのフルスタックなリアクティブ・フレームワークで、百日行の企画で初めてのMeteor製のアプリケーションという事になります。
また、画面の雰囲気も以前にとりあげた『Let’s Chat』のようにとても今風なアプリケーションです。

基本情報

手順の概要は以下の通りです。

  • 1) ソースコードの取得
  • 2) 事前準備
  • 3) アプリの起動
  • 4) 動作確認

1. ソースコードの取得

$ git clone https://github.com/RocketChat/Rocket.Chat
$ cd Rocket.Chat

2. 事前準備

2.1. MongoDBのサービスインスタンス作成

$ cf create-service "Mongo DB" "Default Mongo Plan" rocket-mongo

2.2. アプリの事前push

RocketChat用のmeteor向けbuildpackのURLをapp.json(Heroku Button用の設定ファイル)から確認します。

$ cat app.json
  "env": {
      "BUILDPACK_URL": "https://github.com/RocketChat/heroku-buildpack-meteor.git",

-bで先ほど調べたbuildpackのURLを指定し、–no-startを指定します。

$ cf push rocket -b https://github.com/RocketChat/heroku-buildpack-meteor.git --no-start

2.3. サービスの紐付け

作成したサービスインスタンスをアプリに紐づけます。

$ cf bind-service rocket rocket-mongo

2.4. 環境変数設定

紐づけたサービスの情報を得るために『cf env』を実行し、credentialsのuri部分をメモします。

$ cf env rocket
:
    "credentials": {
     "uri": "mongodb://68608217-650b-4b26-91df-e70ad5105a34:password@192.168.15.82:27017/f9d8d716-8426-42a6-bd62-585aecfe43d1"
    },

cf set-envでMONGO_URLという変数に先ほどメモしたcredentialsの値を設定します。

$ cf set-env rocket MONGO_URL "mongodb://68608217-650b-4b26-91df-e70ad5105a34:password@192.168.15.82:27017/f9d8d716-8426-42a6-bd62-585aecfe43d1"

cf set-envでROOT_URLという変数にアプリのURLと同じ値を設定します。

cf set-env rocket ROOT_URL https://rocket.10.244.0.34.xip.io

さらに、以下の環境変数も設定します。

cf set-env rocket NODE_ENV production
cf set-env rocket LCB_SECRETS_COOKIE secret

3. アプリの起動

$ cf start rocket
:
 
App started
 
 
OK
 
App rocket was started using this command `.meteor/heroku_build/bin/node .meteor/heroku_build/app/main.js`
 
Showing health and status for app rocket in org develop / space develop-space as admin...
OK
 
requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: rocket.10.244.0.34.xip.io
last uploaded: Fri Sep 18 01:28:14 UTC 2015
stack: cflinuxfs2
buildpack: https://github.com/RocketChat/heroku-buildpack-meteor.git
 
     state     since                    cpu    memory           disk      details
#0   running   2015-09-18 10:58:02 AM   0.0%   134.7M of 256M   0 of 1G

成功しました。

4. 動作確認

ブラウザーでアクセス。
Sign up:

Sing in後:

メッセージ入力:

試しに別のユーザーも作成してSing up & Sing in後にメッセージ入力を試してみます。

今回使用したソフトウェア

2015-10-16

CommaFeed を Cloud Foundry で動かす

「Cloud Foundry 百日行」第80日目,今日は「個人的に探しているフィード・リーダー」シリーズ (第1弾: Feedbin, 第2弾: Tiny Tiny RSS) の第3弾 (&多分最後になる予定) で CommaFeed です。Java の Dropwizard という framework を使って実装されています。

基本情報

手順の概要は以下の通りです。

  • 1) ソースコードの取得
  • 2) アプリのビルド
  • 3) サービスの作成とバインド
  • 4) 設定ファイルの作成とJARファイルの更新
  • 5) 環境変数の設定 (manifest.yml の作成)
  • 6) アプリのデプロイ
  • 7) 動作確認

1. ソースコードの取得

GitHub からソースコードを clone して,ディレクトリーを移動します。

$ git clone https://github.com/Athou/commafeed.git
..
$ cd commafeed/

2. アプリのビルド

Cloud Foundry の java-buildpack では,アプリをあらかじめビルドしてからデプロイする必要があります。
アプリの README の記述 (リンク) を参考に,ビルドを行います。

$ ./mvnw clean package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building CommaFeed 2.3.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
..
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:52 min
[INFO] Finished at: 2015-10-12T04:57:03+09:00
[INFO] Final Memory: 60M/569M
[INFO] ------------------------------------------------------------------------

target/commafeed.jar ができているはずです。

$ ls target/commafeed.jar
target/commafeed.jar

3. サービスの作成とバインド

CommaFeed はデータの永続化に DBMS を使います。デフォルトでは H2 を使うようになっているのですが,これはローカルファイルにデータを格納するようになっているので,Cloud Foundry 上だと再起動でデータが消えてしまいます。そこで今回は PostgreSQL サービスを使うことにしました。

アプリのアップロード

アプリを停止状態で Cloud Foundry 上に push します。

$ cf push commafeed -p target/commafeed.jar --no-start
Creating app commafeed in org nota-ja / space 100 as nota-ja...
OK
..

サービスの作成

PostgreSQL サービスを作成します。

$ cf create-service PostgreSQL "Basic PostgreSQL Plan" pg-commafeed
Creating service instance pg-commafeed in org nota-ja / space 100 as nota-ja...
OK
..

サービスのバインド

アプリとサービスをバインドします。

$ cf bind-service commafeed pg-commafeed
Binding service pg-commafeed to app commafeed in org nota-ja / space 100 as nota-ja...
OK
..

4. 設定ファイルの作成とJARファイルの更新

CommaFeed の起動には設定ファイルが必須なので,作成します。さらに,その設定ファイルをアップロードできるよう,JARファイルに格納します。

設定ファイルの作成

config.yml.example をコピーして,内容を適宜修正します。

$ cp config.yml.example config.yml
$ emacs config.yml

主な修正は,以下の3点です。

  • pulicUrl
    アプリの URL と一致するように設定してください
  • allowRegistrations
    アプリケーション画面からのユーザー登録を可能にしてください
    本アプリは管理用画面があり,そこからユーザー登録することもできるのですが,Cloud Foundry 上では今のところ1つのアプリに複数のポートを割り当てることができないので(現在それを可能にする作業が進められています),今回はアプリケーション画面からの登録を可能にするようにしました
  • database
    cf env を実行して, VCAP_SERVICES のデータベース接続情報に基づいて値を設定してください
$ cf env commafeed
Getting env variables for app commafeed in org nota-ja / space 100 as nota-ja...
OK

System-Provided:
{
 "VCAP_SERVICES": {
  "PostgreSQL": [
   {
    "credentials": {
     "uri": "postgres://ea4badfa-a871-4237-a534-9d69fb464200:v2qmkpa772n1r35gdqrko158nr@192.168.15.91:5432/ea4badfa-a871-4237-a534-9d69fb464200"
    },
    "label": "PostgreSQL",
    "name": "pg-commafeed",
    "plan": "Basic PostgreSQL Plan",
    "tags": [
     "PostgreSQL",
     "Database storage"
    ]
   }
  ]
 }
}
..

最終的な変更箇所は以下のようになりました:

$ git diff --no-index -- config.yml.example config.ymldiff --git a/config.yml.example b/config.yml
index 5f6d167..2f7e219 100644
--- a/config.yml.example
+++ b/config.yml
@@ -2,13 +2,13 @@
 # ------------------
 app:
   # url used to access commafeed
-  publicUrl: http://localhost:8082/
+  publicUrl: http://commafeed.10.244.0.34.xip.io/^M

   # wether to allow user registrations
-  allowRegistrations: false
+  allowRegistrations: true^M

   # create a demo account the first time the app starts
-  createDemoAccount: false
+  createDemoAccount: true^M

   # put your google analytics tracking code here
   googleAnalyticsTrackingCode:
@@ -49,7 +49,7 @@ app:
   queryTimeout: 0

   # time to keep unread statuses (in days), 0 to disable
-  keepStatusDays: 0
+  keepStatusDays: 90^M

   # entries to keep per feed, old entries will be deleted, 0 to disable
   maxFeedCapacity: 500
@@ -75,10 +75,10 @@ app:
 # url is jdbc:jtds:sqlserver://localhost:1433/commafeed;instance=<instanceName, remove if not needed>

 database:
-  driverClass: org.h2.Driver
-  url: jdbc:h2:/home/commafeed/db;mv_store=false
-  user: sa
-  password: sa
+  driverClass: org.postgresql.Driver^M
+  url: jdbc:postgresql://192.168.15.91:5432/ea4badfa-a871-4237-a534-9d69fb464200^M
+  user: ea4badfa-a871-4237-a534-9d69fb464200^M
+  password: v2qmkpa772n1r35gdqrko158nr^M
   properties:
     charSet: UTF-8
   validationQuery: "/* CommaFeed Health Check */ SELECT 1"
@@ -95,9 +95,9 @@ server:
       port: 8084

 logging:
-  level: WARN
+  level: INFO^M
   loggers:
-    com.commafeed: INFO
+    com.commafeed: DEBUG^M
     liquibase: INFO
     io.dropwizard.server.ServerFactory: INFO
   appenders:

さきに挙げた主要3点以外については,各自お好みに合わせて設定してください。

JAR ファイルの更新

作成した設定ファイルを Cloud Foundry 上に持っていくために,target/commafeed.jar に追加します。

$ jar uvf target/commafeed.jar config.yml
adding: config.yml(in = 3411) (out= 1531)(deflated 55%)

5. 環境変数の設定 (manifest.yml の作成)

Cloud Foundry の java-buildpack で Dropwizard の JAR ファイルを起動するには,

  • java コマンドの引数で待受ポートを指定する
  • Main class (com.commafeed.CommaFeedApplication) の引数でコマンドと設定ファイルを指定する

必要があります。

今回は,以下の方法を用いました。

  • java コマンドに引数を渡す方法として JAVA_OPTS 環境変数を使う (参考リンク)
  • Executable JAR の Main-Class で指定されたクラスに引数を渡す方法として JBP_CONFIG_JAVA_MAIN 環境変数を使う (参考リンク)
    【余談】
    • これは,もともとは java-buildpack を fork して, config/java_main.yml を書き換えるという方法で行うものでした
    • v3.0 で,これら設定ファイルの中身を環境変数から与える方法が導入されて,いちいち fork をしなくて済むようになりました
    • この「環境変数から与える方法」は,少しトリッキーなのですが,概略は以下のようになります
      config/<設定名>.yml (例: open_jdk_jre.yml) というファイルの中身を環境変数から与える場合:
      • JBP_CONFIG_<大文字化した設定名> (例: JBP_CONFIG_OPEN_JDK_JRE) という環境変数に,
      • flow-style の YAML で設定を記述する (例: '[jre: { version: 1.7.0_+ }]')

これらの環境変数設定も含め,アプリの push に必要な情報を manifest.yml にまとめます。

$ cat manifest.yml
---
applications:
- name: commafeed
  path: target/commafeed.jar
  memory: 1024M
  buildpack: https://github.com/cloudfoundry/java-buildpack.git#v3.3
  services:
  - pg-commafeed
  env:
    JAVA_OPTS: '-Djava.net.preferIPv4Stack=true -Ddw.server.applicationConnectors[0].port=\$PORT'
    JBP_CONFIG_JAVA_MAIN: '[arguments: "server ./config.yml"]'

メモリは多めに1GBに設定しました。また config/java_mail.yml のサポートは java-buildpack v3.2 からで,今回使用した bosh-lite ベースの Cloud Foundry 環境 (cf-release v211) の標準である java-buildpack v3.0 ではサポートされていなかったので,最新のリリースである v3.3 をインターネット上から取ってくるように設定しました。

6. アプリのデプロイ

準備が整ったので,アプリをデプロイします。

$ cf push
..
requested state: started
instances: 1/1
usage: 1G x 1 instances
urls: commafeed.10.244.0.34.xip.io
last uploaded: Mon Oct 12 06:56:07 UTC 2015
stack: cflinuxfs2
buildpack: https://github.com/cloudfoundry/java-buildpack.git#v3.3

     state     since                    cpu      memory         disk      details
#0   running   2015-10-12 04:35:59 PM   105.4%   485.1M of 1G   0 of 1G

起動しました。

7. 動作確認

アプリのURLにアクセスすると,Welcome 画面にリダイレクトされます:

ユーザーを登録します:

ユーザー登録が済むと,自動的にログイン状態になります:

左上の【Subscribe】ボタンを押して,フィードを登録してみます:

登録に成功すると,未読記事のタイトル一覧が表示されます:

記事タイトルをクリックすると,記事を読むことができます:

上部やや右よりにある歯車形ボタンをクリックすると,設定画面に入れるので,言語を日本語にしてみます:

【Save】をクリックすると通常画面に戻ります。

メニュー等が日本語になっていることが確認できました:

以上で動作確認は終わりです。

使ってみた印象では,メモリは多めに必要ですが,動作は軽快で安定していて,機能はシンプルですが必要なものは揃っている感じです。日本語のサポートは珍しいと感じました。

このアプリは,他にパスワードを忘れた際のメイル送信機能や,Redis をキャッシュとして利用する機能もありますが,今回は時間切れで試せませんでした。また,管理者画面についても今回は動作確認対象から外しましたが, JAVA_OPTS の設定を変更して管理者画面にアクセスできることは確認できたので,切り替えができるようにしたいとは思いました。

今回使用したソフトウェア

2015-10-15

WizardWarz を Cloud Foundry で動かす

「Cloud Foundry 百日行」第79日目は、Node.jsで動く多人数参加型ゲーム、 WizardWarz です。

基本情報

今回の手順の概要は以下の通りです。

  • 1) ソースコードの入手
  • 2) ソースコードの修正
  • 3) Cloud Foundryへのデプロイ
  • 4) 動作検証

なお、今回のアプリケーションにはWebSocketが使われています。
Proxyを跨いだ先にCloud Foundryの環境を構築している方は今回のアプリケーションが正常に動作しない可能性がありますので、ご了承下さい。

1. ソースコードの入手

githubからcloneしてきます。

$ git clone https://github.com/lallassu/wizardwarz
~
$ cd wizardwarz
wizardwarz$ ls
css  fonts  icons  images  index.html  js  LICENSE  models  promo.png  README.md

Githubの README を見てみると、Node.jsのアプリケーションのようです。

2. ソースコードの修正

では、Cloud Foundry上で動作するようにソースコードの修正を行っていきます。
修正済みのコードも こちら に用意しておきましたので、これを用いれば手順3までスキップできます。適宜ご利用下さい。

package.jsonファイルの作成

Cloud Foundryにデプロイする際に「このアプリはNode.jsのアプリである」と認識させるために、 package.json ファイルを作っておきましょう。
これは本来Node.jsのパッケージ管理ツールであるnpmの設定ファイルに当たるものですが、今回は特に管理する必要のあるパッケージは存在しないので、 npm init の後Enterキー連打でOKです。

wizardwarz$ npm init
~
wizardwarz$ ls
css  fonts  icons  images  index.html  js  LICENSE  models  package.json  promo.png  README.md  server  sounds  textures

起動ポート番号の指定

さて、次にアプリが起動する際のポート番号を正しく取得できるように指定します。
現在の起動ポート番号は 8080 の固定値になっているので、Cloud Foundry上で起動した際の数値を環境変数 PORT から取れるようにしてみましょう。

wizardwarz$ vi server/server.js
~
//======================================================
// Configuration
//======================================================
var version = "0.1";
var port =  process.env.PORT || 8080;
~
wizardwarz$ git diff --no-prefix server/server.js
diff --git server/server.js server/server.js
index 94f1a64..11a8e03 100644
--- server/server.js
+++ server/server.js
@@ -10,7 +10,7 @@
 // Configuration
 //======================================================
 var version = "0.1";
-var port = 8080;
+var port = process.env.PORT || 8080;
 
 //======================================================
 // Initialization

環境変数 PORT がある場合はそこから値を取得、無い場合は従来通り8080を利用、という変更です。

自身を指定するアドレスの変更

さらにコードを読んでみると、 localhost:8080 を呼び出している箇所があります。
ここの値もデフォルトのままではアプリが正しく動かないので、修正します。

wizardwarz$ vi js/game.js
~
var net = new Net();
//net.Initialize("http://192.168.1.124:8080");
//net.Initialize("http://192.168.1.137:8080");
//net.Initialize("http://nergal.ipeer.se:8080");
//net.Initialize("http://nergal.se:80");
//net.Initialize("http://192.168.1.137:80");
//net.Initialize("http://localhost:8080");
net.Initialize(location.host);
~
wizardwarz$ git diff --no-prefix js/game.js
diff --git js/game.js js/game.js
index 56c94de..a4d6d79 100644
--- js/game.js
+++ js/game.js
@@ -43,7 +43,8 @@ var net = new Net();
 //net.Initialize("http://nergal.ipeer.se:8080");
 //net.Initialize("http://nergal.se:80");
 //net.Initialize("http://192.168.1.137:80");
-net.Initialize("http://localhost:8080");
+//net.Initialize("http://localhost:8080");
+net.Initialize(location.host);
 
 
 //$('#song').prop("volume", 0.8);

ちなみに、この js/game.js というファイルはNode.jsのサーバーを構成するものではなく、アプリのユーザが動かすブラウザ上の index.html から呼び出されるファイルなので、 アプリの環境変数 process.env から取ってくる値は用いないことに注意して下さい。

Buildpack周りの修正

今回はNode.jsのアプリなのでNode.jsのBuildpackで動いてくれそうなものですが、Node.jsのBuildpackだけだとどうしても、sqlite3関連のライブラリが一部足りないというエラーを吐いてアプリが起動しない、という現象を回避できませんでした。
そこで今回は、好きなaptパッケージをインストールすることができる heroku-buildpack-apt というBuildpackを一緒に動かすことでデプロイを行いました。
これらの2つのBuildpackを同時に使うためにはこれまでの記事にも何度か登場した heroku-buildpack-multi を使います。

まずは heroku-buildpack-multi で呼び出したいBuildpackを .buildpacks ファイル内に記載します。

wizardwarz$ vi .buildpacks 
https://github.com/ddollar/heroku-buildpack-apt#7954acd0aa932201377187402d8a0794f535c738
https://github.com/cloudfoundry/nodejs-buildpack#eaf93a153ccb1c7780457ca611c45311d95a6259

バージョンを固定するためにhashで指定をしています。

次に heroku-buildpack-apt にapt-getしてきて欲しいパッケージ名を Aptfile 内に記載します。

wizardwarz$ vi Aptfile
sqlite3
libsqlite3-dev

これでOKです。
ちなみにNode.jsのBuildpackは package.json ファイルを用意してあるので自動的に動いてくれます。

manifestファイルの作成

最後に manifest.yml ファイルも作っておきます。

wizardwarz$ vi manifest.yml
---
applications:
- name: wizardwarz
  buildpack: https://github.com/ddollar/heroku-buildpack-multi#c41ef671cc9c8ff7d5cc7ad412654fbf9cffbce5
  command: cd server; node server.js;

3. Cloud Foundryへのデプロイ

ではCloud Foundry上へPushしてみましょう。

wizardwarz$ cf push
(一部略)
-----> Uploading droplet (54M)

1 of 1 instances running

App started


OK

App wizardwarz was started using this command `cd server; node server.js;`

Showing health and status for app wizardwarz in org ukaji / space default as ukaji...
OK

requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: wizardwarz.10.244.0.34.xip.io
last uploaded: Sat Oct 10 04:21:08 UTC 2015
stack: cflinuxfs2
buildpack: https://github.com/ddollar/heroku-buildpack-multi

     state     since                    cpu    memory          disk      details   
#0   running   2015-10-10 01:22:03 PM   0.1%   61.2M of 256M   0 of 1G  

起動はOKです。

4. 動作検証

では払いだされたURLにブラウザでアクセスしてみます。

メイン画面はこちら。

NEWPLAYER からプレイヤーを作ってログインしてみます。

遊び方は

  • マウスカーソルで視点移動
  • WSADでキャラクターを前後左右へ移動
  • Mapに落ちているアイテムを拾って画面上の対応する数字キーで各種呪文を選択、マウスクリックで発動

といった感じのようです。

今回使用したソフトウェア

2015-10-14

EtherDraw を Cloud Foundry で動かす

「Cloud Foundry 百日行」第78日目,今回は「Etherシリーズ(?)」の描画アプリ,EtherDraw です。複数人で画面を共有してキャンバスに絵を描くことができるアプリで,描画機能としては基本的なものしかありませんが,子どもたちに使ってもらったりすると面白いかもしれません。あとは,遠隔でのホワイトボード共有には使えそうです。終わったら SVG / PNG でエクスポートできるので情報の保存も容易ですし,物理ホワイトボードと違って消去もワンクリックで済みます。

基本情報

手順の概要は以下の通りです。

  • 1) ソースコードの取得
  • 2) デプロイ準備
  • 3) アプリのデプロイ
  • 4) 動作確認
  • 5) 永続化

1. ソースコードの取得

GitHub からソースコードを clone します。今回はディレクトリー名を指定して clone しています。

$ git clone https://github.com/JohnMcLear/draw.git etherdraw

ディレクトリーを移動します。

$ cd etherdraw/

2. デプロイ準備

2.1. node モジュールの事前インストール

このままの状態で Cloud Foundry にデプロイするとステージングに失敗したので,調査した結果,このアプリで利用している canvas というモジュールに問題があることがわかりました。

cf. gyp: fix pangocairo detection by LinusU - Pull Request #600 - Automattic/node-canvas

このままでは動作しないので,上記 pull request で提案されている node モジュールのインストールを実行します。

$ npm install LinusU/node-canvas#pangocairo-test

これで,Cloud Foundry 上で compile 時に問題を起こすモジュールの修正版がローカルに生成され, cf push の際にソースコードと一緒にアップロードされるので,ステージングに失敗しなくなります。

【注】必要ライブラリーの事前インストール

ローカル環境でこの npm install を成功させるには, このページ (リンク) に書かれているライブラリーを事前にインストールしておくことが必要です。

もし上記 npm コマンドの実行に失敗した場合は,以下を実施後,再度実行してみてください。

以下はローカル環境が Ubuntu であるという前提で進めます。他の環境については, ここ (リンク) からご自分の環境を選んで,その記述に従ってください。

Ubuntu では,以下を実行します。

$ sudo apt-get update 
$ sudo apt-get install libcairo2-dev libjpeg8-dev libpango1.0-dev libgif-dev build-essential g++

これにより,node モジュールのインストールに必要なライブラリーがインストールされます。

2.2. package.json の修正

2.1 節のコマンドの実行に成功すると,使われる canvas モジュールのバージョンが変わるので,それに合わせて package.json を修正します。

$ emacs package.json
..
$ git diff -- package.json
diff --git a/package.json b/package.json
index de5bd41..b5d9369 100755
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
     "socket.io": "~1.0.0",
     "async": "~0.6.2",
     "ueberDB": "~0.2.1",
-    "canvas": "1.2.1",
+    "canvas": "1.2.4",
     "paper": "0.9.22",
     "jsonminify":"~0.2.3"
   }

2.3. アプリの待受ポートの修正

本アプリは待受ポートを環境変数から設定することができないので,それができるようにソースコードを修正します。

$ emacs server.js
..
$ git diff -- server.js
diff --git a/server.js b/server.js
index 598bf88..6627f53 100755
--- a/server.js
+++ b/server.js
@@ -15,6 +15,10 @@ var settings = require('./src/util/Settings.js'),
     http = require('http'),
     https = require('https');

+if (process.env.PORT) {
+    settings.port = process.env.PORT;
+}
+
 /**
  * SSL Logic and Server bindings
  */

これで, PORT という環境変数がある場合はその値を使い,ない場合は従来通りの動作になります。

2.4. settings.json の作成

最後に,設定ファイル settings.json を作成します。といっても,テンプレートをコピーするだけです。

$ cp settings.json.template settings.json

この設定では,データの保存先としてファイルを使用する DBMS である dirtydb を使うので,再起動するとデータが全て消えてしまいますが,試しに使うだけであればこれでOKですので,今回はこのままで行きます。

外部のデータベースにデータを永続化する方法については,5 節に書きますので,そちらをご覧ください。

3. アプリのデプロイ

準備が整ったので,アプリをデプロイします。

$ cf push etherdraw
..
OK

App etherdraw was started using this command `node server.js`

Showing health and status for app etherdraw in org nota-ja / space 100 as nota-ja...
OK

requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: etherdraw.10.244.0.34.xip.io
last uploaded: Wed Oct 14 04:20:38 UTC 2015
stack: cflinuxfs2
buildpack: Node.js

     state     since                    cpu    memory           disk      details
#0   running   2015-10-14 01:27:56 PM   0.0%   104.5M of 256M   0 of 1G

起動しました。

4. 動作確認

アプリのURLにアクセスすると,ランダム生成された URL を持つ作業画面にリダイレクトされます:

ブラシで字を書いてみました:

ペンで字を書いてみました:

色を変えてみます:

ブラシで色を塗ってみました:

他の人にアクセスしてもらって,絵を描いてもらいました:

わかりにくいかもしれませんが,右上の人型アイコンの横の数字が, 2 になっています。

以上で動作確認は終わりです。

5. 永続化

さて,このままですと,(さきに述べたように) アプリが再起動されるとせっかく描いた絵が全て消えてしまいます。描いた絵が消えないようにするためには,データベースを使って永続化します。DBMS としては, settings.json.template 内で例として挙げられている MySQL を使うことにしました。

5.1. サービスの作成

$ cf create-service p-mysql 100mb mysql-etherdraw
Creating service instance mysql-etherdraw in org nota-ja / space 100 as nota-ja...
OK

5.2. アプリとサービスのバインド

$ cf bind-service etherdraw mysql-etherdraw
Binding service mysql-etherdraw to app etherdraw in org nota-ja / space 100 as nota-ja...
OK
TIP: Use 'cf restage etherdraw' to ensure your env variable changes take effect

5.3. データベース接続設定の変更

アプリが MySQL に繋がるよう,設定を変更します。

まず,データベース接続情報を cf env で確認します。

$ cf env etherdraw
..
 "VCAP_SERVICES": {
  "p-mysql": [
   {
    "credentials": {
     "hostname": "10.244.7.6",
     "jdbcUrl": "jdbc:mysql://10.244.7.6:3306/cf_486b7f41_74eb_4f55_adbb_f514e9c63f75?user=pBxKgJ3l5NDUi4WP\u0026password=1yOxeXgyHXXlGrc2",
     "name": "cf_486b7f41_74eb_4f55_adbb_f514e9c63f75",
     "password": "1yOxeXgyHXXlGrc2",
     "port": 3306,
     "uri": "mysql://pBxKgJ3l5NDUi4WP:1yOxeXgyHXXlGrc2@10.244.7.6:3306/cf_486b7f41_74eb_4f55_adbb_f514e9c63f75?reconnect=true",
     "username": "pBxKgJ3l5NDUi4WP"
    },
    "label": "p-mysql",
    "name": "mysql-etherdraw",
    "plan": "100mb",
    "tags": [
     "mysql"
    ]
   }
  ]
 }
..

上記の情報をもとに,設定ファイル settings.json のデータベース接続設定の部分を書き換えます。

元の設定との差分はこうなります。

$ git diff --no-index -- settings.json.template settings.json
diff --git a/settings.json.template b/settings.json
index c29599f..bba5e99 100644
--- a/settings.json.template
+++ b/settings.json
@@ -11,21 +11,23 @@

   //The Type of the database. You can choose between dirty, postgres, sqlite and mysql
   //You shouldn't use "dirty" for for anything else than testing or development
+  /*
   "dbType" : "dirty",
   //the database specific settings
   "dbSettings" : {
      "filename" : "var/dirty.db"
   },
+  */

-  /* An Example of MySQL Configuration
+  /* An Example of MySQL Configuration */
   "dbType" : "mysql",
   "dbSettings" : {
-    "user"    : "root",
-    "host"    : "localhost",
-    "password": "",
-    "database": "etherdraw"
+    "host"    : "10.244.7.6",
+    "port"    : 3306,
+    "user"    : "pBxKgJ3l5NDUi4WP",
+    "password": "1yOxeXgyHXXlGrc2",
+    "database": "cf_486b7f41_74eb_4f55_adbb_f514e9c63f75"
   },
-  */

   /* The default selected tool - 'pencil', 'brush', 'select' */
   "tool": "brush"

5.4. アプリの更新

設定ファイルの更新を反映させるため,アプリをプッシュします。

$ cf push etherdraw
..
     state     since                    cpu    memory           disk      details
#0   running   2015-10-14 01:21:31 PM   0.8%   105.1M of 256M   0 of 1G

起動しました。

5.5. 動作確認

こんな絵が描かれた状態で:

アプリを再起動します。

$ cf restart etherdraw

再起動中は 404 が出てアクセス不能になりますが:

     state     since                    cpu    memory           disk      details
#0   running   2015-10-14 03:06:42 PM   0.3%   104.4M of 256M   0 of 1G

アプリ起動後にアクセスすると,もとの絵が残っています:

(といってもこの図ではよくわかりませんが..)

今回使用したソフトウェア

2015-10-13

dhtmlxScheduler を Cloud Foundry で動かす

本日の第77回「Cloud Foundry百日行」は dhtmlxScheduler です。

クラウドサービスベンダーのカレンダーサービスをつかって、イベント等の管理はもはや普通になってきていますが、 会社のポリシーとして利用禁止ということもあるでしょう。困った事情として、たとえば Google カレンダー に慣れてしまって、社内のは使いにくい!というクレームもあるかもしれません。

今回紹介するのは、DHTMLX という WEBアプリケーションフレームワーク上の Scheduler サンプルです。百日行の趣旨から少し外れますが、サンプルの割には、Googleカレンダーのように使え、 実用的という意味であえて紹介したいと思いました。

基本情報

デプロイ

1. ソースコードの取得

オリジナルのソースコードを Cloud Foundry の IBM版である Bluemix で動作するように変更したものがあるので、 そちらを利用します。オリジナルの Cloud Foundry で動かす場合には多少ソースの変更が必要だと 思いますが、さほど難しくはないと思われます。

$ git clone https://github.com/dtoczala/ULLCloudCalendar.git
$ cd ULLCloudCalendar

オリジナルからの修正は、

  • Mongo DB を Cloud Foundry のサービスとしてバインドさせるようにした
  • port 変数を 3000 から process.env.VCAP_APP_PORT を読み取るようにした
  • Single Sign On (SSO) を実装した

です。SSO の部分は、恐らく 無視できるでしょう。 Mongo DB の利用は変更する必要があります。変更する場合は、


var mongo_creds = services['mongolab'][0]['credentials'];
var mongo_uri            = mongo_creds['uri'];


のあたりを見れば問題ないかと思います。

なお、今回のソフトウェアは GPL v2 で、 サンプルは GPL v3 です。修正した場合などの扱いにはライセンス条項にしたがってください。

2. Cloud Foundry にデプロイ

Cloud Foundry にデプロイしてみましょう。mongodb を利用しているので、それを用意します。 Bluemix 用の変更は Mongolab を使うようになっています。

$ cf create-service mongolab sandbox mongodb_amntcalendar

残念ながら、改変版のソースでも manifest.yml ファイルの問題でうまく動作しないので、 すべての設定をマニュアルで実施します。

$ mv manifest.yml manifest.yml.original
$ cf push amntcalendar -m 256M -c "node app.js" -n amntcalendar -d mybluemix.net --no-start
$ cf bind-service amntcalendar mongodb_amntcalendar
$ cf start amntcalendar

1 of 1 instances running
App started
requested state: started
instances: ?/1
usage: 256M x 1 instances
urls: amntcalendar.mybluemix.net
last uploaded: Fri Oct 9 07:01:26 UTC 2015
stack: cflinuxfs2

   state     since                    cpu    memory          disk          details
#0   running   2015-10-09 04:10:03 PM   0.0%   59.4M of 256M   55.2M of 1G

正常にアプリケーションが稼働しました。

動作確認

それでは動作を簡単に確認してみましょう。起動したURLをたたくと見たことの あるようなカレンダーが表示されます。




ひとつ追加してみます。





全日のイベントも入れられるようです。



おまけ

社内のソフトウェア開発では、開発の状況をダッシュボードで確認できるようになっています。 チームミーティングで、「共有できるカレンダーとかあるといいよね?」という話が出てきました。 ダッシュボードだと、プラグインかなにかで対応できるのですが、ダッシュボード以外からも アクセスした場合もあるかも?ということで、このカレンダーをウィジェットとして 組み込んでみるという試みをしたのがこのソフトウェアを使うようになったきっかけです。

もちろん外部には公開したくないので、社内の小さな Cloud Foundry 環境で動作 させています。このあたりのよもやま話が、関連情報にあるブログに書いてあります。 GPL なので改変したソースも公開している理由もその一つです。

開発でちょっとしたカレンダーを共有するには、ちょうどよいレベルだと思いますので、 皆様も如何でしょうか?

今回使用した環境


2015-10-09

Battleboat.jsを Cloud Foundry で動かす

「Cloud Foundry 百日行」第76日目は、海戦ゲーム Battleboat.js です。
このアプリはロボット相手にゲームをするので対人間のような心理戦が出来ません。純粋に運と計算で勝つしか方法がありません。
海戦ゲームを知らない人も簡単に出来るので一度試してみて下さい。

基本情報

今回の手順の概要は以下の通りです。

  • 1) ソースコードの入手
  • 2) Cloud Foundry上へのデプロイ
  • 3) 動作検証

1. ソースコードの入手

$ git clone https://github.com/Kortaggio/battleboat.git
$ cd battleboat/
battleboat$ ls
css  img  index.html  js  LICENSE.txt  README.md

Githubからソースコードをcloneしてきます。

2. Cloud Foundry上へのデプロイ

デプロイも中身を見ていただいたらわかる通りこれまで何度となく登場しているStatic_buildpackでOKです。

battleboat$ touch Staticfile
battleboat$ cf push battleboat -m 16M -k 128M

:
-----> Uploading droplet (3.4M)

1 of 1 instances running

App started


OK

App battleboat was started using this command `sh boot.sh`

Showing health and status for app battleboat in org k-nagai / space work as k-nagai...
OK

requested state: started
instances: 1/1
usage: 16M x 1 instances
urls: battleboat.10.244.0.34.xip.io
last uploaded: Wed Oct 7 07:13:01 UTC 2015
stack: cflinuxfs2
buildpack: Static file

     state     since                    cpu    memory        disk        details   
#0   running   2015-10-07 04:13:08 PM   0.0%   4.7M of 16M   0 of 128M      

デプロイ完了です。

3. 動作検証

URLにアクセスします。

少し下にスクロールすると二つのマス目の描いた画面が表示されます。ウィンドウのサイズによっては縦に並んでいるかもしれません。

右のメニューから “Patrol Boat”,”Submarine”,”Destroyer”,”Battleship”,”Aircraft Carrier” と並んでいるのでそれぞれ選んで、”Your Fleet” に配置します。
(参考) 配置する船はそれぞれ2,3,3,4,5マスになっていますので被らないように配置するだけです。縦横変えたい場合は “Rotate Ship” で変えることが出来ます。

配置が完了したら “Start Game” でゲーム開始です。
“Enemy Fleet” にカーソルを合わせて1箇所選びます。相手が船を配置していた場合は赤バツ、外れた場合は白バツになります。この際、相手が何処を選んだかが “Your Fleet” にも表示されます。

これを繰り返して1つの船が破壊されるとそのマスが黒くなり、相手より先に相手が配置したすべての船を破壊すれば勝利です。

問題なく動作しています。

おまけ

READMEに書かれていますが、このゲームはbotの改善の為の勝敗データをGoogle Analyticsを使って集めているようです。利用される方は作者の意図に沿って使って下さいね。

今回使用したソフトウェア

2015-10-08

PullUp を Cloud Foundry で動かす

「Cloud Foundry 百日行」第75日目、本日のアプリは PullUp 。これは、ある話題に対してコメント、また評価していくといったもので、先日取り上げた Pumpkin にも似たコミュニティツールです。

このアプリは Node.js 製で、Mongo DB を使います。そして、Node.js から MongoDB にアクセスするためのライブラリ Mongoose が内部で使われています。

またこのアプリの仕様としての面白いところは、それ自身のツール内での参加メンバの活動を活性化させるための仕組みです。そもそもコミュニティというのは、参加メンバが積極的に活動することで成り立つものです。このアプリでは、サインアップの条件として、このアプリの改善に貢献し、GitHub のアプリ本家へプルリクエストを出して、ユーザ登録してもらうことで初めてフルに機能を使える、というハードルを設けています。それによって、参加メンバのツール内活動が必然的に活発になる、という仕組みになっています。

基本情報

手順の概要は以下の通りです。

  • 1) ソースコードの取得
  • 2) アプリのデプロイ
  • 3) 動作確認

1. ソースコードの取得

まずはソースコードを取得します。

~$ git clone https://github.com/larvalabs/pullup
~$ cd pullup
~/pullup$ ls
app.js          components  constants.js     controllers     forever.js    gulpfile.js                  LICENSE  package.json  Procfile.local  README.md  test   vagrant      views
cluster_app.js  config      CONTRIBUTING.md  _Design Assets  Gruntfile.js  hackathon-starter-readme.md  models   Procfile      public          tasks      utils  Vagrantfile

2. アプリのデプロイ

Development Setup の手順を参考にします。

2.1 Mongo DB サービスの作成とバインド

Mongo DB が必要になっているので、その対応をしますが、まずは --no-start でプッシュしておきます。

~/pullup$ cf push pullup --no-start
Creating app pullup in org ueno / space test1 as ueno...
OK

Using route pullup.10.244.0.34.xip.io
Binding pullup.10.244.0.34.xip.io to pullup...
OK

Uploading pullup...
Uploading app files from: /home/ueno/pullup
Uploading 721.3K, 165 files
Done uploading               
OK

Mongo DB サービスを作成します。

~/pullup$ cf create-service 'Mongo DB' 'Default Mongo Plan' mongo-pullup

そして、アプリと Mongo DB サービスをバインド。

~/pullup$ cf bind-service pullup mongo-pullup

2.2 環境設定

Development Setup で指定されている環境変数を設定します。

~/pullup$ cf set-env pullup GITHUB_CLIENTID 'CLIENTID'
~/pullup$ cf set-env pullup GITHUB_SECRET 'SECRET'

ここでもう一つ。Mongo DB の URL を設定しておく必要があります。

ソースコードでは、 config/secrets.js にて、

~/pullup$ cat config/secrets.js
module.exports = {
  db: process.env.MONGOHQ_URL || 'localhost',

:

とあるように、Mongo DB の URL は、設定されていない場合のデフォルト値が localhost になっています。

このファイルのこの箇所を書き換えてもいいのですが、ここでは、環境変数 MONGOHQ_URL に環境設定することにします。

~/pullup$ cf set-env pullup MONGOHQ_URL 192.168.15.91

では、アプリに対して実行した一連の環境設定を確認しておきましょう。

~/pullup$ cf env pullup
Getting env variables for app pullup in org ueno / space test1 as ueno...
OK

System-Provided:
{
 "VCAP_SERVICES": {
  "Mongo DB": [
   {
    "credentials": {
     "uri": "mongodb://f9e5a2c2-5893-4abc-b2f8-715a0e6a8f0d:password@192.168.15.91:27017/9185e646-4e60-4269-a14a-f594d38ab357"
    },
    "label": "Mongo DB",
    "name": "mongo-pullup",
    "plan": "Default Mongo Plan",
    "tags": [
     "mongodb",
     "document"
    ]
   }
  ]
 }
}

{
 "VCAP_APPLICATION": {
  "application_name": "pullup",
  "application_uris": [
   "pullup.10.244.0.34.xip.io"
  ],
  "application_version": "accada52-d52a-452e-851c-b8f92a037934",
  "limits": {
   "disk": 1024,
   "fds": 16384,
   "mem": 256
  },
  "name": "pullup",
  "space_id": "b4706364-1075-4cb5-82dc-5b8b45571434",
  "space_name": "test1",
  "uris": [
   "pullup.10.244.0.34.xip.io"
  ],
  "users": null,
  "version": "accada52-d52a-452e-851c-b8f92a037934"
 }
}

User-Provided:
GITHUB_CLIENTID: CLIENTID
GITHUB_SECRET: SECRET
MONGOHQ_URL: 192.168.15.91

No running env variables have been set

No staging env variables have been set

Mongo DB の接続情報、そして、先ほど設定した GITHUB_CLIENTID , GITHUB_SECRET , MONGOHQ_URL 等の情報が確認できました。

2.3 アプリのデプロイ

ではアプリをデプロイします。

このアプリは、Node.js を使うので、 Development Setup に指定されている通り、デプロイの際、 node app.js を -c オプションによって実行させます。

~/pullup$ cf push pullup -c 'node app.js'
Updating app pullup in org ueno / space test1 as ueno...
OK

:

App started


OK

App pullup was started using this command `node app.js`

Showing health and status for app pullup in org ueno / space test1 as ueno...
OK

requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: pullup.10.244.0.34.xip.io
last uploaded: Wed Oct 7 06:32:16 UTC 2015
stack: cflinuxfs2
buildpack: Node.js

     state     since                    cpu    memory          disk      details   
#0   running   2015-10-07 03:33:28 PM   0.0%   98.3M of 256M   0 of 1G    

アプリが起動しました。

3. 動作確認

ブラウザからアプリにアクセスします。

右上にある Signup をクリックしてみると、

「本アプリのユーザになるためには、プルリクエストするしかありません」とはねつけられましたね。

本日のところは、プルリクまでは割愛して、その限られた権限でも使えるチャット機能を確認しましょう。

画面上の Chat のリンクをクリック。

画面下の LOGIN WITH GITHUB TO START TALKING をクリックすると、GitHub の OAuth のページに飛び、アプリからの認証連携の許可を求められます。
許可すると、GitHub 認証によってログインでき、チャットできます。

ちなみに、このチャット機能の実体は Gitter です。
https://gitter.im/larvalabs/pullup にアクセスすると、同じ内容が表示されます。

まとめ

今回のアプリは、Node.js 製で、Mongo DB へアクセスするためのライブラリ Mongoose が内部では使われていました。今回は、Mongo DB の URL として、ソースコードのデフォルト値を上書きするために、環境変数 MONGOHQ_URL を設定しました。それをせずとも動的に DB 接続できるコーディングがクラウドでは理想ですが、そこはまた別途の機会とします。

PullUp の基本的な作りを振り返っておきたいと思います。サービス機能としては、 News , Issues , Chat の3つで、それぞれ提供形態が異なります。 News は、任意のコミュニティにおける活動(話題提供、コメント、評価等)を支援する本アプリのメインです。しかしながら、利用するには、PullUp 本家へプルリクエストし、権限付与の登録をしてもらう必要があります。 Issues は、本家の GitHub と連携し、GitHub での Issues における(本アプリ開発に関する)議論と紐付くようになっているようです。 Chat は、本家の Gitter と連携し、Gitter 上でチャットする形態になります。

本家ではプルリクを受けてマージする際、 config/userlist.js に該当の GitHub のアカウントを登録するようですが、ローカルで同じように検証してみると、それだけでは権限付与されませんでした。やはり、本家へのプルリクが必須のようです。それがもし、ローカルコミュニティ内に閉じたプルリク & 登録でフル機能が使えるようになると、そのアプリとその仕組みは各地でローカルに使うことができるようになるのでいいですよね。残念ながら現状は本アプリはそのようにローカルに閉じては使えないので、頑張れる読者は是非改善を検討して本家へプルリク出してみてください!

今回使用したソフトウェア