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

2015-07-15

FlappyTube を Cloud Foundry で動かす

「Cloud Foundry 百日行」第30日目は,某有名ゲームのクローンである FlappyTube です。

基本情報

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

  • 1) ソースコードの取得
  • 2) Cloud Foundry 環境へのプッシュ
  • 3) 動作確認

1. ソースコードの取得

$ git clone https://github.com/flynngao/FlappyTube
$ cd FlappyTube/
FlappyTube$ ls
bower_components  bower.json  gulpfile.coffee  gulpfile.js  index.coffee  index.html  index.js  LICENSE  package.json  README.md  res

~.coffee などがありますが既に ~.js にビルド済みのようなので、いつも通りのStaticfile扱いで行けそうです。

2. Cloud Foundry 環境へのプッシュ

さて、実は 第25日目の記事 でも同じような現象が起こったのですが、このアプリもBuildpackの特定をCloud Foundry任せにしてしまうとNodeJSと判定されてしまいます。ということで今回もstaticfile-buildpackを明示的に指定してあげましょう。

FlappyTube$ cf push flappytube -b staticfile_buildpack
(一部略)
-----> Uploading droplet (4.2M)

1 of 1 instances running

App started


OK

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

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

requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: flappytube.10.244.0.34.xip.io
last uploaded: Wed Jul 15 03:41:50 UTC 2015
stack: cflinuxfs2
buildpack: staticfile_buildpack

     state     since                    cpu    memory         disk      details   
#0   running   2015-07-15 12:42:02 PM   0.0%   6.2M of 256M   0 of 1G

アプリが起動しました。

3. 動作確認

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

本家とは逆に、土管を飛ばして謎の生命体(?)を取得していくというゲームのようです。
皆さんも是非チャレンジしてみてください。

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

2015-07-14

Editr を Cloud Foundry で動かす

本日の第29回「Cloud Foundry 百日行」は Editr です。
これは、Web のデモページをブラウザ上で作りながらリアルタイムで確認できるアプリになっています。

基本情報

ソースコードの取得と確認

$ git clone https://github.com/Idered/Editr.js.git
$ cd Editr.js/
$ ls
editr  README.md  test

README のインストール手順の最初に、”Copy editr folder to root of your website.” とありますが、今回は Cloud Foundry へデプロイするので、 editr/ フォルダ自体に入ってそこで確認したい html を作成し、そこからアプリを push します。

$ cd editr/
$ ls
editr.css  editr.js  items  libs  parsers

index.html の作成

アプリと一緒に配布されているサンプルファイルを使い、 README を参考に、 index.html を作成します。

まずはサンプルファイルの test/projects/index.html を editr/ にコピーして持ってきます。

$ pwd
/home/ueno/Editr.js/editr
$ cp -p ../test/projects/index.html .
$ cp -p index.html index.html.org
$ cat index.html 
<!DOCTYPE html>
<html lang="en">
<head>
    <title></title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body></body>
</html>

この index.html を編集します。

$ vi index.html
$ cat index.html 
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Editr</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
 
    <link rel="stylesheet" href="editr.css">
</head>
<body>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="//cdn.jsdelivr.net/ace/1.1.01/min/ace.js"></script>
    <script src="//cdn.jsdelivr.net/ace/1.1.01/min/ext-emmet.js"></script>
    <script src="libs/ext.emmet.js"></script>
    <script src="editr.js"></script>
    <script src="libs/parser.coffeescript.js"></script>
    <script src="libs/parser.less.js"></script>
 
    <div class="editr"></div>
 
    <script>
    $('.editr').each(function() {
        new Editr({
            el: this,
        });
    });
    </script>
</body>
</html>
$ diff index.html.org index.html
4c4
<     <title></title>
---
>     <title>Editr</title>
6a7,8
> 
>     <link rel="stylesheet" href="editr.css">
8c10,28
< <body></body>
---
> <body>
>     <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
>     <script src="//cdn.jsdelivr.net/ace/1.1.01/min/ace.js"></script>
>     <script src="//cdn.jsdelivr.net/ace/1.1.01/min/ext-emmet.js"></script>
>     <script src="libs/ext.emmet.js"></script>
>     <script src="editr.js"></script>
>     <script src="libs/parser.coffeescript.js"></script>
>     <script src="libs/parser.less.js"></script>
> 
>     <div class="editr"></div>
> 
>     <script>
>     $('.editr').each(function() {
>         new Editr({
>             el: this,
>         });
>     });
>     </script>
> </body>

アプリの push

今回のアプリは HTML, JavaScript を主として構成されていますが、一部、PHP のファイルも存在しています。
それに対し、今回使用している bosh-lite 環境には、php-buildpack が入っていますので、特定の buildpack の指定はせずにそのまま push します。

$ cf push editr
Creating app editr in org ueno / space test1 as ueno...

:

requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: editr.10.244.0.34.xip.io
last uploaded: Thu Jul 9 10:15:49 UTC 2015
stack: cflinuxfs2
buildpack: PHP
 
     state     since                    cpu    memory          disk      details   
#0   running   2015-07-09 07:16:07 PM   0.0%   27.9M of 256M   0 of 1G  

デプロイ成功し、アプリが起動しました。
buildpack: PHP から、php-buildpack が使用されたことがわかりますね。

動作確認

http://editr.10.244.0.34.xip.io にアクセス。

HTML のサンプルとして、アプリについているサンプルファイルを使ってみましょう。
test/projects/flat-ui/switch.html の中身を HTML の画面にコピペします。

続いて、 test/projects/flat-ui/switch.css の中身も CSS の画面にコピペ。

そして、Result 画面を出すと、

switch.html と switch.css が解釈されて、画面表示されました。

push 時にファイルを読み込む方法の確認

このアプリは複数のファイルをあらかじめ読み込ませ、その中から選択表示できるので、今度はそれを確認していきます。

まずはサンプルファイルが入ったフォルダ test/projects/flat-ui を持ってきます。

$ pwd
/home/ueno/Editr.js/editr
$ cp -pr ../test/projects/flat-ui .
$ ls flat-ui
main.less  normalize.css  radio.css  radio.html  script.coffee  switch.css  switch.html

この中から、先ほど使った、 switch.html , switch.css と共に、 radio.html と radio.css の計4つのファイルを読み込ませるため、サンプルファイル test/index.html を参考に、上記で作った index.html を編集します。

$ pwd
/home/ueno/Editr.js/editr
$ cp -p index.html index.html.1
$ vi index.html 
$ cat index.html 
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Editr</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
 
    <link rel="stylesheet" href="editr.css">
</head>
<body>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="//cdn.jsdelivr.net/ace/1.1.01/min/ace.js"></script>
    <script src="//cdn.jsdelivr.net/ace/1.1.01/min/ext-emmet.js"></script>
    <script src="libs/ext.emmet.js"></script>
    <script src="editr.js"></script>
    <script src="libs/parser.coffeescript.js"></script>
    <script src="libs/parser.less.js"></script>
 
    <div class="editr" data-files-html="switch.html;radio.html" data-files-css="main.less;switch.css;radio.css"></div>
 
    <script>
    $('.editr').each(function() {
        new Editr({
            el: this,
            path: 'flat-ui',
            view: 'vertical',
            gistProxyURL: 'libs/proxy.gist.php',
            callback: function(editr) {}
        });
    });
    </script>
</body>
</html>
$ diff index.html.1 index.html
19c19
<     <div class="editr"></div>
---
>     <div class="editr" data-files-html="switch.html;radio.html" data-files-css="main.less;switch.css;radio.css"></div>
24a25,28
>             path: 'flat-ui',
>             view: 'vertical',
>             gistProxyURL: 'libs/proxy.gist.php',
>             callback: function(editr) {}

ファイルの編集が終わったので、アプリを push します。

$ cf push editr2
Creating app editr2 in org ueno / space test1 as ueno...

:

requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: editr2.10.244.0.34.xip.io
last uploaded: Thu Jul 9 10:31:35 UTC 2015
stack: cflinuxfs2
buildpack: PHP
 
     state     since                    cpu    memory          disk      details   
#0   running   2015-07-09 07:31:50 PM   1.7%   23.6M of 256M   0 of 1G    

デプロイ成功してアプリが起動したので、アクセスします。

switch.html と switch.css が解釈されて、画面出力されています。

Result, HTML, CSS の各タグをクリックすると、読み込んだファイルが選択できるようになっています。

Result のタグから、 radio.html に切り替えてみると、その内容に画面が切り替わりました。

まとめ

今回は、デプロイ自体は簡単に出来た割には、そのアプリは、ブラウザ上で、HTML/JavaScript/CSSを作成、編集、組み合わせて、そのまま実行可能、という便利なものでした。
Webサーバ上のコンテンツを直接編集、なんて使い方もできるかもしれません。もちろんセキュリティと認証の課題をクリアする必要はありますが。

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

2015-07-13

Lockee を Cloud Foundry で動かす

「Cloud Foundry 百日行」第28日目は、 Lockee です。
こちらはWeb上でコインロッカー風にファイルを保存できるアプリケーションになります。

基本情報

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

  • 1) ソースコードの取得
  • 2) コードの修正
  • 3) Cloud Foundry 環境へのプッシュ
  • 4) 動作確認

1. ソースコードの取得

まずはいつも通りコードを取得しましょう。

$ git clone https://github.com/hbons/Lockee
$ cd Lockee
Lockee$ ls
config.json  covers.json  LICENSE.txt  lockee.service  package.json  public  README.md  server.js  tests  views

NodeJS製のアプリですね。

2. コードの修正

LockeeのReadme によるとこのアプリ、コードを取得してしまえば後は npm install npm start の2つのコマンドで起動できてしまうそうです。
実際にCloud Foundry上での起動時の手続自体はそう難しいものではありませんでした。

しかし、今回のアプリは正常に動かすために少しだけコードに手を加える必要があったため、まずはそれを片付けてしまいましょう。

正しいバージョンのNodeを指定

今回のアプリは、動かすためのNodeのバージョンに指定があるためまずはそれを指定しましょう。
NodeJSのアプリケーションではお馴染みの package.json ファイルの編集によって指定ができます。

Lockee$ vi package.json
{
  "name": "Lockee",
  "version": "1.0.0",
  "description": "Temporary encrypted file lockers on the web.",
  "repository": {
    "type": "git",
    "url": "https://github.com/hbons/Lockee"
  },
  "main": "server.js",
  "author": "Hylke Bons",
  "contributors": [
    {
      "name": "Hylke Bons",
      "email": "hi@planetpeanut.uk"
    }
  ],
  "license": "AGPLv3",
  "engines": {
    "node": "0.10.33"
  },
  "dependencies": {
    "express": "~4.12.2",
    "jade": "~1.9.2",
    "sqlite3": "~2.1.1",
    "body-parser": "~1.12.0",
    "compression": "~1.4.3",
    "node-sass": "~3.0.0-alpha.0",
    "async": "~0.9.0",
    "helmet": "~0.7.1",
    "node-schedule": "~0.2.6"
  },
  "scripts": {
    "clean": "rm ./blobs.db && rm -Rf ./blobs/"
  }
}
Lockee$ git diff
diff --git a/package.json b/package.json
index 41b7ec9..bcc348e 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,9 @@
     }
   ],
   "license": "AGPLv3",
+  "engines": {
+    "node": "0.10.33"
+  },
   "dependencies": {
     "express": "~4.12.2",
     "jade": "~1.9.2",

これでNodeのバージョンの指定は完了です。

Cloud Foundry上でのHOST名、PORT名を取得するための設定

まずは説明の前にコードの修正から行います。

Lockee$ vi server.js
(一部略)
// Server
var port = process.env.PORT || process.env.OPENSHIFT_NODEJS_PORT || config.server.port
var ip   = process.env.VCAP_APP_HOST || process.env.OPENSHIFT_NODEJS_IP   || '127.0.0.1'
(一部略)
Lockee$ git diff
diff --git a/server.js b/server.js
index 1d228f9..c662fca 100644
--- a/server.js
+++ b/server.js
@@ -387,8 +387,8 @@ function getCover(hash) {
 
 
 // Server
-var port = process.env.OPENSHIFT_NODEJS_PORT || config.server.port
-var ip   = process.env.OPENSHIFT_NODEJS_IP   || '127.0.0.1'
+var port = process.env.PORT || process.env.OPENSHIFT_NODEJS_PORT || config.server.port
+var ip   = process.env.VCAP_APP_HOST || process.env.OPENSHIFT_NODEJS_IP   || '127.0.0.1'
 
 if (config.server.ssl.enabled) {
     var credentials = {

この修正で何を行ったかというと・・・
元々のコードでは、

  • PORT番号 → OPENSHIFTで動かす時のPORT、なかったらconfigファイルから取得(3000番)
  • IPアドレス → OPENSHIFTで動かす時のIP、なかったらlocalhost

となっています。
しかしこのアプリをCloud Foundry上で動かしたい場合、実はPORT番号やIPアドレスは事前に決め打ちできるものでもなく、もちろん process.env.OPENSHIFT~~~ で取得できるものでもありません。
やっていることはOPENSHIFTで動かすときの環境変数の取得方法とそう変わらないのですが、Cloud Foundry上のアプリの環境変数を取得できるコードを書き加え、

  • PORT番号 → Cloud Foundryで動かすときのPORT、なかったらOPENSHIFTで動かす時のPORT、なかったらconfigファイルから取得(3000番)
  • IPアドレス → Cloud Foundryで動かすときのIP、なかったらOPENSHIFTで動かす時のIP、なかったらlocalhost

のように変更を行いました。

(おまけ)Domain名の変更

これはアプリを起動する上ではあまり影響のない箇所ですが、起動したアプリと関係のないドメイン名が随所に表示されていると少し格好が悪いので変更しておきましょう。

Lockee$ vi config.json 
{
    "server": {
        "production": false,
        "domain":     "lockee.10.244.0.34.xip.io",
        "port":       3000,
        "ssl": {
            "enabled":     false,
            "port":        3001,
            "privateKey":  "ssl/server.key",
            "certificate": "ssl/server.crt"
        },
        "admin": {
            "name":         "Hylke Bons",
            "contact_info": "https://www.twitter.com/hbons"
        }
    },
    "locker": {
        "location":   "./blobs/",
        "database":   "blobs.db",
        "size_limit": "20mb",
        "time_limit": 86400,
        "covers":     "/images/covers/"
   }
}
Lockee$ git diff
diff --git a/config.json b/config.json
index e2ae9e5..87db9e4 100644
--- a/config.json
+++ b/config.json
@@ -1,7 +1,7 @@
 {
     "server": {
         "production": false,
-        "domain":     "lockee.me",
+        "domain":     "lockee.10.244.0.34.xip.io",
         "port":       3000,
         "ssl": {
             "enabled":     false,

3. Cloud Foundry 環境へのプッシュ

それでは、Cloud FoundryにアプリをPushしましょう。

Lockee$ cf push lockee
(一部略)

-----> Uploading droplet (20M)

1 of 1 instances running

App started


OK

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

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

requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: lockee.10.244.0.34.xip.io
last uploaded: Fri Jul 10 08:32:37 UTC 2015
stack: cflinuxfs2
buildpack: Node.js

     state     since                    cpu    memory          disk      details   
#0   running   2015-07-10 05:34:27 PM   0.0%   51.3M of 256M   0 of 1G 

無事起動しました。

4. 動作確認

それでは、動作確認を行います。
URLにアクセスをして、画面下のGO TO LOCKERから適当な名前のロッカーを作ってみましょう。

こちらがロッカー画面。
中々にお洒落な感じです。
試しに適当なファイルを放り込んでみると・・・

Passphraseを決めてファイルにロックを掛けましょう。

ロックが掛かったファイルは24時間有効のようです。
取り出すときはもちろん先ほどのPassphraseで。

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

2015-07-10

KADOS を Cloud Foundry で動かす

本日の第27回「Cloud Foundry 百日行」は KADOS です。
公式ホームページには”KADOS is web-based tool for managing SCRUM projects and other Agile projects”と書かれており、スクラム開発やアジャイル開発に用いられるカンバンをWEBのダッシュボードで提供してくれるアプリです。
アプリはPHPとMySQLで構成されており、第10回の記事で紹介した方法で簡単に利用が可能です。
なお事前にお知らせしておくと”Kados is available in French, English,Spanish and soon German version”となっており、ヨーロッパ圏向けのサポートとなっているので、一部言語ではメニューが文字化けを起こします。チケットなどの入力は日本語でも動作させることが出来ましたので実行上はEnglishで進めれば普通に利用は可能です。

基本情報

デプロイ

手順
  • 0) ソースコードの取得
  • 1) アプリの起動
  • 2) 動作確認

ソースコードの取得

今回は公式のホームページからzipファイルをダウンロードし解凍します。
解凍するとnew_installとupgrade用のディレクトリが現れますので今回はnew_installを選びましょう。
$ wget http://downloads.sourceforge.net/project/kados/kados_r8-SilverBird.zip
$ unzip kados_r8-SilverBird.zip -d kados_work
$ rm kados_r8-SilverBird.zip
$ cd kados_work
$ ls
kados_changelog_r8.txt  new_install_r8  upgrade_from_v1.7.1_to_r8
$ cd new_install_r8/
$ ls
install_EN.txt install_FR.txt kados  licence sql
とりあえずEnglish版のインストールマニュアルがあるので確認します。
手順はこんな感じです。
  • 0) DBの接続情報を準備(サポートはMySQL database version 5)
  • 1) /kadosディレクトリをWebServerにrootか/kadosとして配置
  • 2) SQLスクリプトをMySQL databaseに実行
  • 3) confフォルダを開く
  • 4) connect.conf にパラメータを設定(MySQLの接続情報)
  • 5) サイトにアクセスしてadmin/adminでログイン
  • 6) メールでユーザのアクティベーションするなら以下を設定(以下略)
  • 7) ヘルプは ドキュメント を参照、あるいは http://www.kados.info/en へ問い合わせ
なお今回は6のメール連携は利用しない方法で進めます。
機会があればそちらも試してみます。

アプリの起動

手順通りcf pushする対象のkadosディレクトリに移動します。
そして次の手順に備えて--no-startオプションをつけてcf pushしてしまいましょう。
$ cd kados
$ cf push kados --no-start
あとはいつも通りMySQLをServiceで準備しましょう。
$ cf marketplace

service      plans                     description   
p-mysql      100mb-dev, 1gb-dev        A MySQL service for application development and testing   

$ cf create-service p-mysql 100mb-dev kados_db
$ cf bind-service kados kados_db
$ cf env kados
System-Provided:
{
 "VCAP_SERVICES": {
  "p-mysql": [
   {
    "credentials": {
     "hostname": "10.244.1.18",
     "jdbcUrl": "jdbc:mysql://10.244.1.18:3306/cf_6eafb097_998c_4d32_beb1_96b1a6bc0db4?user=yPoaMwFiVm4kjatg\u0026password=9Y6e4ZAhaRbIWozF",
     "name": "cf_6eafb097_998c_4d32_beb1_96b1a6bc0db4",
     "password": "9Y6e4ZAhaRbIWozF",
     "port": 3306,
     "uri": "mysql://yPoaMwFiVm4kjatg:9Y6e4ZAhaRbIWozF@10.244.1.18:3306/cf_6eafb097_998c_4d32_beb1_96b1a6bc0db4?reconnect=true",
     "username": "yPoaMwFiVm4kjatg"
    },
    "label": "p-mysql",
    "name": "kados_db",
    "plan": "100mb-dev",
    "tags": [
     "mysql"
    ]
   }
  ]
 }
}
:

次にcf pushしたkadosディレクトリにあるconf/connect.confを編集します。
編集内容は
<?php
 
/* -----------*********  Base de donnees   ***********-------*/
// param?tres de connexion
  $PARAM_host="10.244.1.18";
  $PARAM_db="cf_6eafb097_998c_4d32_beb1_96b1a6bc0db4";
  $PARAM_user="vUWLGrGDkn8aDT66";
  $PARAM_password="3NZE7vIOAH50DTPc";
  $PARAM_charset='utf8';
?>
または
<?php
 
/* -----------*********  Base de donnees   ***********-------*/
// paramètres de connexion
  $services = getenv("VCAP_SERVICES");
  $services_json = json_decode($services,true);
  $mysql_config = $services_json["p-mysql"][0]["credentials"];
 
  $PARAM_host= $mysql_config["hostname"];
  $PARAM_db= $mysql_config["name"];
  $PARAM_user= $mysql_config["username"];
  $PARAM_password= $mysql_config["password"];
  $PARAM_charset='utf8';
?>
になります。
あとはcf pushをするだけ。
おっとその前にSQLスクリプトの実行を忘れていました。あぶない、あぶない。
このSQLスクリプトはkadosディレクトリの1つ上のsqlディレクトリの中にcreate_database_r8.sqlのファイル名で準備されています。
今回は以前紹介した同じPHPアプリの第17回 SQL Buddyを使いました。
  • デプロイ手順は過去の記事を確認して戴きたいのですが、そこで使われる外部のphp-buildpackはデフォルトサポートバージョンが変更されておりますので、エラーの出る方はtag v3.2.2を指定して利用してみて下さい(過去の百日行記事で、staticfile-buildpackを使うアプリでも同じような事象がありました)。
  • SQLスクリプトのインポートの際には1箇所insert into framework_parameters_values_listsのコマンドが長過ぎてエラーになるので中盤あたりでコマンドを2つに分割して下さい。
スクリプト変更方法
該当コマンドの中盤あたりで
),(
を
); \n insert into `framework_parameters_values_lists`(`parameter_tag_id_fk`,`parameter_value_label`,`parameter_value`) values (

に置き換えます。大体コマンドが半分くらいになれば問題ないと思います。
SQLスクリプトの修正が終われば、それをSQL Buddyでデータベースを指定して上部メニューの”Import” の機能を使って読み込ませます。
エラーまたはアプリがダンマリにならなければ成功です。
ではあらためてcf pushしましょう。
$ cf push kados

:
requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: kados.10.244.0.34.xip.io
last uploaded: Thu Jul 2 07:54:12 +0000 2015
stack: lucid64
 
     state     since                    cpu    memory          disk      details   
#0   running   2015-07-02 04:54:55 PM   0.0%   96.2M of 256M   0 of 1G      
デプロイ完了です。

動作確認

URL kados.10.244.0.34.xip.io にアクセスしてみます。
ログインはID admin/PASS admin。
ログイン出来ればDB接続も問題なく出来ています。
文字化けしている場合は左上のイギリスの国旗を選んで英語に変更。

ユーザ追加やプロジェクト作成などいろいろ試して見て下さい。

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

2015-07-09

tty.js を Cloud Foundry で動かす

本日の第26回「Cloud Foundry 百日行」はブラウザ上で動作するターミナル tty.js です。

昨日の第25回「Cloud Foundry 百日行」で、ブラウザ上で動作するターミナル ButterFly を試しましたが、ログインが必要なので実運用で問題になりそうでした。今回はログインがいらないターミナル "tty.js" を試してみます。

基本情報


デプロイ

"tty.js" のソースコードを入手してデプロイもできるかと思いますが、"tty.js"  は npm パッケージ化されているので、Cloud Foundry へのデプロイ過程にて取得し、実行する方法をとりました。

1. 準備

"tty.js" は Node.jsランライムで実行されるアプリケーションです。package.json に "tty.js" を dependency として記述すると Node.js ビルドパックがデプロイ時に取得してくれます。


$ cat package.json
{
  "dependencies": {
        "tty.js": "0.2.14-1"
  }
}

用意するファイルは package.json だけです。簡単ですね。


2. デプロイ

npm パッケージは node_modules ディレクトリに保管されるので、実行コマンドを "node node_modules/tty.js/bin/tty.js -p $PORT" とします。


$ cf push amnttty -c 'node node_modules/tty.js/bin/tty.js -p $PORT' -m 256M

App amnttty was started using this command `node node_modules/tty.js/bin/tty.js -p $PORT`



requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: amnttty.mybluemix.net
last uploaded: Wed Jul 8 04:46:34 UTC 2015
stack: lucid64

     state     since                    cpu    memory          disk          details
#0   running   2015-07-08 01:47:30 PM   0.0%   36.6M of 256M   58.8M of 1G

なお今回の Cloud Foundry は Bluemix を利用しました。

動作確認

正常にデプロイできたら、アプリケーションURL にアクセスします。




"tty.js" のバナーに "Open Terminal"ボタンがあるのでそれをクリックします。するとターミナルが開きます。Open Terminal をクリックすると複数のターミナルが起動するようです。

いくつかコマンドを動かしてみました。



vi エディターも動くようです。




なお、"tty.js" の課題として、文字のコピーはできるがペーストする手段がないことがあげられています。ここは将来のバージョンで修正して欲しいところです。


まとめと余談

Cloud Foundry のコンテナに端末として入りたいという理由がいくつかあります。
  • コンテナで使われている rootfs の内容が知りたい
  • 自分のPCは Windows だが急遽 Linux が必要になった
  • ネットワークが不調なので、別のマシンからアクセスさせてみたい (curl の利用等)
"cf-ssh" などを利用した端末アクセス方法がありますが、今回紹介した tty.js では、ペーストできないという欠点を除けば、比較的簡単にアクセスできるようになると思われます。しかしながら、ログインしないでアクセス出来てしまうので、目的を達成したらアプリケーションは停止しておくことを推奨します。


余談

この記事を書いた1週間前には、package.json ファイルの dependencies の記述を "tty.js": "*" のようにしていたのですが、再度確認しようと思った時に動かなくなってしまいました。よくみると最新版だと思っていた "0.2.14"が依存する複数のパッケージが npm リポジトリから削除されているのがわかりました。有志があつまりいろいろ検索してくれた結果、-1 を付ければよいということが判明し、無事記事として出せるようになった顛末があります。Node.js で npm リポジトリからパッケージが削除されることがあるという良い経験になりました。


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


  • cf-release Bluemix (v210)

  • tty.js v0.2.14-1
    https://github.com/chjj/tty.js/tree/v0.2.14-1



2015-07-08

Butterfly を Cloud Foundry で動かすことはできたが,使えなかった

「Cloud Foundry 百日行」第25日目は,ブラウザー上で動作するターミナル Butterfly です。

タイトルからわかるように,今回,百日行シリーズ初の「失敗」を述べる記事になります。Cloud Foundry も万能ではなく,当然動作に適さないアプリも中にはあるのですが,それを明らかにすることもまた有益であると考え,今回記事として公開する次第です。

基本情報

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

  • 1) ソースコードの取得
  • 2) コードの修正
  • 3) Cloud Foundry 環境へのプッシュ
  • 4) 動作確認
  • 5) (おまけ) Cloud Foundry 環境の管理者権限を使っての動作確認

1. ソースコードの取得

$ git clone https://github.com/paradoxxxzero/butterfly.git
$ cd butterfly/

いつも通りです。

2. コードの修正

requirements.txt の修正

プッシュする前に,requirements.txt に不足しているライブラリーがあるので,それを追加します。

$ emacs requiments.txt
..
$ git diff
diff --git a/requirements.txt b/requirements.txt
index e20c23a..9117c11 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1 +1,2 @@
 tornado>=3.2
+tornado_systemd

3. Cloud Foundry 環境へのプッシュ

このアプリは Python ベースなのですが,bosh-lite 環境にプッシュすると NodeJS アプリと判定され,NodeJS buildpack でステージングが行われてしまいます。

これは,NodeJS buildpack の detect (buildpack を適用するかどうかを判定するスクリプト) が「アプリのトップ・ティレクトリーに package.json というファイルがあるか」を判定基準にしていて,

https://github.com/cloudfoundry/nodejs-buildpack/blob/a65dd4c348923ac63f0f436bf890b583c5aa3ea9/bin/detect#L4

if [ -f $1/package.json ]; then

かつ,実際にこのアプリのトップ・ディレクトリーに package.json があり,

https://github.com/paradoxxxzero/butterfly/blob/ed03f94c8447fc186bfd9eb44f6c678e059fa35a/package.json

さらに,NodeJS buildpack の適用順位が Python buildpack よりも前にあるために起きる現象です。

$ cf buildpacks
Getting buildpacks...

buildpack              position   enabled   locked   filename
java_buildpack         1          true      false    java-buildpack-v3.0.zip
ruby_buildpack         2          true      false    ruby_buildpack-cached-v1.4.2.zip
nodejs_buildpack       3          true      false    nodejs_buildpack-cached-v1.3.1.zip
go_buildpack           4          true      false    go_buildpack-cached-v1.3.1.zip
python_buildpack       5          true      false    python_buildpack-cached-v1.3.2.zip
php_buildpack          6          true      false    php_buildpack-cached-v3.2.1.zip
staticfile_buildpack   7          true      false    staticfile_buildpack-cached-v1.0.0.zip
binary_buildpack       8          true      false    binary_buildpack-cached-v1.0.0.zip

そこで,プッシュ時に陽に Python buildpack を使うよう指定します。

さらに今回は,アプリの起動コマンドも指定して,アプリをプッシュします。

$ cf push butterfly -b python_buildpack -c 'python butterfly.server.py --port=$PORT --host=$VCAP_APP_HOST --unsecure'
..
requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: butterfly.10.244.0.34.xip.io
package uploaded: Tue Jul 7 11:46:07 UTC 2015
stack: cflinuxfs2

     state     since                    cpu    memory          disk      details
#0   running   2015-07-07 08:46:46 PM   0.0%   58.8M of 256M   0 of 1G

アプリが起動しました。

4. 動作確認

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

最初の画面はこんな感じです:

GitHub の README に貼ってあるのとよく似た画面が表示されています。

「起動した!」と思ったのですが,ここで問題発生。

Cloud Foundry のアプリは,Warden というコンテナー内で起動するのですが,その際のユーザーは vcap になっています。そこで login: プロンプトに vcap と打ち込んで enter を押したところでハタと気づきました。

「パスワードがわからない」

そうなのです。パスワードがわからないと,ログインできませんし,当然何のコマンドも実行できません。

ということで,今回のアプリ Butterfly は,起動まではできたのですが,残念ながら「使えない」という結果になりました。

なお,時期は未定ですが,Cloud Foundry の次のメジャー・リリースである v3 では, アプリのインスタンスにSSHでアクセスできる機能が追加される予定 です。この機能があれば,Butterfly が「使える」ようになるかもしれません。

5. (おまけ) Cloud Foundry 環境の管理者権限を使っての動作確認

ここからは完全におまけですが,Cloud Foundry 環境の管理者権限を使って,コンテナー内の vcap ユーザーにパスワードを設定し,そのパスワードでログインして本当にアプリが動作しているかを試してみます。

百日行シリーズの「ユーザーの視点から Cloud Foundry の使い方を示す」という趣旨からは外れますが,個人の興味の範囲で試してみました。

各コマンドの詳細な説明は省略しますので,質問等あれば,別途ご連絡ください。

  • Warden コンテナーが動作している DEA にログインします
$ bosh ssh runner_z1/0

  • スーパーユーザーになって,
bosh_4xqfadsn8@dab3959e-f426-4ef6-8602-34be08a31058:~$ sudo -s
  • アプリのインスタンスが動作しているコンテナーを特定し,
root@dab3959e-f426-4ef6-8602-34be08a31058:~# find /var/vcap/data/warden/depot/ -name butterfly.server.py
/var/vcap/data/warden/depot/18q8si997t6/tmp/rootfs/home/vcap/app/butterfly.server.py
root@dab3959e-f426-4ef6-8602-34be08a31058:~# ps -ef | grep 18q8si997t6
root      7312     1  0 11:46 ?        00:00:00 wshd: 18q8si997t6
root      7349   148  0 11:46 ?        00:00:00 /var/vcap/data/packages/warden/88b0ad837f313990ce408e50cd904f7025983213.1-95fe39abd3b1f23126ab20be93fc7de85b7bec0e/warden/src/oom/oom /tmp/warden/cgroup/memory/instance-18q8si997t6
root      7523   148  0 11:46 ?        00:00:00 /var/vcap/data/warden/depot/18q8si997t6/bin/iomux-spawn /var/vcap/data/warden/depot/18q8si997t6/jobs/47 /var/vcap/data/warden/depot/18q8si997t6/bin/wsh --socket /var/vcap/data/warden/depot/18q8si997t6/run/wshd.sock --user vcap /bin/bash
root      7524  7523  0 11:46 ?        00:00:00 /var/vcap/data/warden/depot/18q8si997t6/bin/wsh --socket /var/vcap/data/warden/depot/18q8si997t6/run/wshd.sock --user vcap /bin/bash
root      7529   148  0 11:46 ?        00:00:00 /var/vcap/data/warden/depot/18q8si997t6/bin/iomux-link -w /var/vcap/data/warden/depot/18q8si997t6/jobs/47/cursors /var/vcap/data/warden/depot/18q8si997t6/jobs/47
root     11131 10869  0 12:19 pts/0    00:00:00 grep --color=auto 18q8si997t6
  • コンテナーに入ります
root@dab3959e-f426-4ef6-8602-34be08a31058:~# /var/vcap/data/warden/depot/18q8si997t6/bin/wsh --socket /var/vcap/data/warden/depot/18q8si997t6/run/wshd.sock /bin/bash
  • コンテナー内で vcap ユーザーのパスワードを変更します
root@18q8si997t6:~# passwd vcap
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
root@18q8si997t6:~# exit
  • ここで,先ほどの画面から vcap ユーザーでログインします
    パスワードは先ほど設定したものを使います

    ログインできました!

  • いろいろやってみました

ということで,irregular な方法ですが,動くことは確認できました。

なお次回は,この結果を受けて,別のターミナル・アプリについて,Takehiko Amano さんが書いてくださる予定です。

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

2015-07-07

SugarCRM を Cloud Foundry で動かす

「Cloud Foundry 百日行」第24日目は,PHP製の CRM (Customer Relationship Management) ソフトウェア SugarCRM (日本語サイト) です。

オープンソースの CRM ソフトウェアとしては非常に有名なので,CRM に興味のある方なら一度は耳にされたこともあるかと思います。CRM に全く関わったことがない私も,名前だけは知っていました。

基本情報

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

  1. ソースコードの取得
  2. Cloud Foundry 環境へのプッシュ
  3. Install Wizard の実行
  4. 動作確認(1)
  5. 再起動後もインストール前の状態に戻らないようにする
  6. 動作確認(2)

ソースコードの取得

$ git clone https://github.com/sugarcrm/sugarcrm_dev.git
$ cd sugarcrm_dev

Cloud Foundry 環境へのプッシュ

SugarCRM を Cloud Foundry 上で動かす際のポイントは

  • 新しい PHP Buildpack (v3.0.4以降) を使う
  • PHP 拡張モジュールを追加する
  • Apache モジュールを追加する

の3点です。

  • 新しい PHP buildpack (v3.0.4以降) を使う

今回検証に利用した v194 環境に標準で入っている PHP buildpack は v1.0.2 なのですが,Cloud Foundry の PHP buildpack は v3.0.4 で大幅なアーキテクチャ変更が入って一新されました。以下に述べる PHP 拡張モジュールや Apache モジュールを追加する機能を利用するために,今回は GitHub 上にある新しい buildpack の URL を指定して使います。
なお,v3.0.4 の PHP buildpack は,cf-release v201 で標準添付されるようになったので,最新版の Cloud Foundruy ではこの点を特に気にする必要はありません。

  • PHP 拡張モジュールを追加する

今回利用する PHP buildpack では, .bp-config/options.json というファイルを利用して PHP 拡張モジュールを追加できます。SugarCRM に必要な拡張モジュールについては, http://www.sugaruser.jp/Documentation/installation_and_upgrade_guide#PHP などを参考にしました。

  • Apache モジュールを追加する

今回利用する PHP buildpack では, .bp-config/httpd/extra/ 以下に httpd-*.conf を置くことで, Apache の設定をカスタマイズできます。標準では SugarCRM に必要な mod_alias が入っていなかったので,.bp-config/httpd/extra/httpd-modules.conf を使って mod_alias を有効にしました。

以上を踏まえて,SugarCRM を Cloud Foundry 上で起動させるまでの手順を見ていきます。

PHP 拡張モジュールの追加

アプリのトップ・ディレクトリーに .bp-config ディレクトリーを作り,そこに以下の内容の options.json ファイルを置きます。

$ mkdir .bp-config
$ emacs .bp-config/options.json
..
$ git diff -- .bp-config/options.json
diff --git a/.bp-config/options.json b/.bp-config/options.json
new file mode 100644
index 0000000..7384d69
--- /dev/null
+++ b/.bp-config/options.json
@@ -0,0 +1,3 @@
+{
+    "PHP_EXTENSIONS": ["mbstring", "zip", "mysql", "mysqli", "gd", "openssl", "bz2", "zlib", "curl", "mcrypt"]
+}

Apache モジュールの追加

http://docs.cloudfoundry.org/buildpacks/php/gsg-php-config.html#engine-configurations を参考に,このファイル を .bp-config/httpd/extra/httpd-modules.conf に置いて,以下の変更を実施します。

$ mkdir -p .bp-config/httpd/extra/
$ cp ../php-buildpack/defaults/config/httpd/2.4.x/extra/httpd-modules.conf
$ emacs .bp-config/httpd/extra/httpd-modules.conf
..
$ git diff -- .bp-config/httpd/extra/httpd-modules.conf
diff --git a/.bp-config/httpd/extra/httpd-modules.conf b/.bp-config/httpd/extra/httpd-modules.conf
index 76f2c4c..1590421 100644
--- a/.bp-config/httpd/extra/httpd-modules.conf
+++ b/.bp-config/httpd/extra/httpd-modules.conf
@@ -111,4 +111,4 @@ LoadModule rewrite_module modules/mod_rewrite.so
 #LoadModule actions_module modules/mod_actions.so
 #LoadModule speling_module modules/mod_speling.so
 #LoadModule userdir_module modules/mod_userdir.so
-#LoadModule alias_module modules/mod_alias.so
+LoadModule alias_module modules/mod_alias.so

mod_alias の行のコメントアウトを外すだけです。

アプリのプッシュ

$ cf push sugar -b https://github.com/cloudfoundry/php-buildpack.git --no-start

GitHub 上の PHP buildpack を使うようオプションを指定して,アプリをプッシュ します。この後 MySQL サービスを作成してバインドするので,この時点ではアプリが起動しないよう --no-start を付けておきます。

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

SugarCRM の標準では,データベースとして MySQL を使うようです。そこで MySQL サービスを作成し,SugarCRM アプリにバインドします。

$ cf create-service p-mysql 100mb-dev my4sugar
Creating service instance my4sugar in org nota-ja / space 100 as nota-ja...
OK
$ cf bind-service sugar my4sugar
Binding service my4sugar to app sugar in org nota-ja / space 100 as nota-ja...
OK
TIP: Use 'cf restage sugar' to ensure your env variable changes take effect

アプリの起動

アプリを起動する準備が整ったので,起動します。

$ cf start sugar
..
requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: sugar.10.244.0.34.xip.io
last uploaded: Thu Jun 18 02:04:17 +0000 2015
stack: lucid64
 
     state     since                    cpu    memory          disk      details
#0   running   2015-06-18 11:05:41 AM   0.0%   44.7M of 256M   0 of 1G

無事起動しました。

Install Wizard の実行

SugarCRM では,初回起動時に Install Wizard が走り,DB接続等の設定を行います。

この記事はあくまで SugarCRM を Cloud Foundry 上で動かすことが主眼であり,SugarCRM 自体のの解説は目的外なので,全ての手順について詳細な説明は省略し,幾つかポイントとなる画面のみを取り上げることにします。

初期画面

起動後最初の画面は以下のようになっています:

Install Wizard 実行前の注意

(略)

ライセンス同意

なぜかライセンスが表示されないのですが, ここ で確認済みなので,【I Accept】にチェックを入れて【Next】をクリックします。

なお,ここでエラーが出る場合は,必須 PHP 拡張モジュールが不足している可能性があります。

インストール・タイプの選択

【Typical Install】を選んで【Next】をクリックします。

データベース選択

MySQL一択です。

DB接続情報入力

この画面では,さきにバインドした MySQL サービスの接続情報に基づいて入力を行います。

MySQL サービスの接続情報は, cf env <アプリ名> で表示される VCAP_SERVICES の中に入っています:

$ cf env sugar
..
"VCAP_SERVICES": {
 "p-mysql": [
  {
   "credentials": {
    "hostname": "10.244.1.18",
    "jdbcUrl": "jdbc:mysql://10.244.1.18:3306/cf_9c38e266_aad4_4c4d_b608_065648fd22f3?user=jfca0SfmmSh8c6TI\u0026password=UWE5ae2yK6znh0VN",
    "name": "cf_9c38e266_aad4_4c4d_b608_065648fd22f3",
    "password": "UWE5ae2yK6znh0VN",
    "port": 3306,
    "uri": "mysql://jfca0SfmmSh8c6TI:UWE5ae2yK6znh0VN@10.244.1.18:3306/cf_9c38e266_aad4_4c4d_b608_065648fd22f3?reconnect=true",
    "username": "jfca0SfmmSh8c6TI"
   },
   "label": "p-mysql",
   "name": "my4sugar",
   "plan": "100mb-dev",
   "tags": [
    "mysql"
   ]
  }
 ]
}
..

入力が終わって【Next】をクリックすると,「DBが既にあるので,中身を初期化するがいいか?」と尋ねるダイアログが出てくるので,【I Accept】をクリックします。指定した名前のDBが存在しない場合は新たにDBを作成してくれるようですが,Cloud Foundry の MySQL サービスの場合,常にDB作成済みの状態でアプリに渡されるので,処理の流れとしては必ずこうなります。

初期管理者のパスワード設定

(略)

設定確認画面

【Install】を押して先に進むと,セットアップ成功画面が表示されます:

ここで【Next】を押してエラーが出る場合,Apache のモジュールの設定に失敗している可能性があります。

製品登録(optional)画面

Optional ということで,何も入力せず次へいきます。するとついに最初のログイン画面に進みます。

動作確認(1)

引き続きログインして動作確認を行います。

SugarCRM では,管理者/ユーザーの最初のログイン時には Admin Wizard, User Wizard を通る必要があるようです。

最初のログイン画面

先ほど「初期管理者のパスワード設定」で入力したユーザー名/パスワードを入力してログインします。

Admin Wizard 画面

面倒なので【Skip】します。

ユーザー情報入力画面

(略)

Locale 設定画面

(略)

User Wizard 最終画面

これを終わると,ようやく使い始めの画面になります。

ログイン後のトップ画面

画面上に赤い文字で記述されている注記は,SMTP サーバーが設定されていないために出ているものです。今回はメイルを送るつもりはなかったので気にしないことにしました。

この後,ユーザー管理画面で一般ユーザーを作ったり(メイル送信が必要になったので,既存の SMTP サーバーを設定して試しました),作った一般ユーザーでログインしたりもしましたが,そのあたりは割愛させていただきます。

再起動後もインストール前の状態に戻らないようにする

通常ならここで終わりですが,今回はもう一歩踏み込んでみます。

SugarCRM は Install Wizard や User Wizard で設定した情報をローカルファイルに持っているため,再起動するとセットアップからやり直しになります。つまり(事実上)継続的には使えません。

そこで今回,これら Wizard で設定した情報が入っているファイルを取得・保存し,コードと一緒に再度プッシュすることで,再起動後もそれまで通り使い続けられるようにすることにトライしてみました。

アプリのリポジトリーのトップ・ディレクトリーは,今回使った PHP buildpack では,app/htdocs/ というディレクトリーに展開されます。そこで,この2つのディレクトリーを比較し,増えたファイルが以下であることを特定しました。

  • .htaccess
  • config.php
  • config_override.php
  • install.log

このうち,ログは不要であろうと判断し,残り3つのファイルを Cloud Foundry 環境からローカルに持ってきます:

$ cf files sugar app/htdocs/.htaccess
..
$ cf files sugar app/htdocs/config.php
..
$ cf files sugar app/htdocs/config_override.php
..

ファイルの内容が端末に表示されるので,コピーして同名のファイルに保存します。

$ ls -1a
..
.htaccess
..
config.php
config_override.php
..

この状態でアプリを再度プッシュします。

$ cf push sugar
Updating app sugar in org nota-ja / space 100 as nota-ja...
OK
.......
requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: sugar.10.244.0.34.xip.io
last uploaded: Tue Jun 23 04:22:19 +0000 2015
stack: lucid64
 
     state     since                    cpu    memory          disk      details
#0   running   2015-06-23 01:23:44 PM   0.0%   44.5M of 256M   0 of 1G

問題なく起動しました。

動作確認(2)

再起動直後の画面

Install Wizard / User Wizard を通ることなくログイン画面に到達しました。

ログイン直後の画面

再起動前に設定した admin ユーザーでログインしてみると,

問題なくログインできて,前回の続きから使うことができました。

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