まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:github

最近、ボット関連の API や SDK をよく見るわりに、自分では使う機会が少なかったので、今更ながら1つ作ってみました。

今回作ってみたのは「シェルボット」です。名前の通り、ボットでシェルっぽいインターフェースを実現しました。何言ってるかよくわからない人はこちらの画面を参照ください:
2017060901



ボットっぽい対話型インターフェースを使って、対話しているかのようにシェルコマンドを実行します。今回はインターフェースに独自の HTML ページを用意しましたが、ぶっちゃけ LINE などでも(Messaging API を使うなどすれば)応用できると思っています。

#「チャットボット」とは違うけど「ボット」ですっ!


ソースコードを github で公開しておきました。セキュリティ的な面はまだまだ改良の余地があると思っています(rm コマンド他は実行不可にしていますが、本当は他にも実行を制御するコマンドを考慮したほうがいいと思う):
https://github.com/dotnsf/shellbot


↑このソースコードはビジュアルフローエディタである Node-RED で使う前提のものです。(IBM Bluemix などを使って)Node-RED 環境を用意し、func-exec ノードを追加した上でキャンバスに shellbot_nodes.txt の内容をインポートして、ブラウザで /shell にアクセスするだけです(詳しくは README.md 参照)。

#あー、あと今のところ Linux/Unix 系 OS に導入する前提です。


実際に Node-RED 環境上にインポートした様子のスクリーンショットがこちらです。2本のシンプルな HTTP リクエスト処理が定義されているだけのもの(うち1つは HTML 画面定義)ですが、本当にこれだけでこのシェルボットが動きます:
2017060902


実は今まで「ボット」=「チャットボット」=「コンシェルジュ」的なイメージを持っていてハードルが高かったのですが、今回のアプリを作った結果、難しく考えずに「既存アプリケーションのインターフェースを対話型にする」という実装もアリかな、と思うようになりました。


2016 年の年初に「マンホライザー」というサービスを作って動かしていました:
http://dotnsf.blog.jp/archives/1048853473.html

マンホライザーはわかりやすく言うと「マンホール顔ハメ画像作成サービス」です(わかりやすいか??)。先日のマンホールサミット 2017 埼玉に参加した際にも、こんなアナログな顔ハメ写真サービスを提供させていただいたのですが、意外と人気があったのでした。それをウェブ上からもできるようにしよう、というわけで生まれたサービスでした。IBM Watson の画像認識機能を使って実装しており、「テクノロジーの無駄使い」な点も自己採点ポイントが高いものになっています(笑):
2017020701


上記リンク先の、2016 年に公開した当初は PHP で実装していました。その時のソースコードはこちらです:
https://github.com/dotnsf/Manholizer


このコードはこれはこれで現在も動く(注 Visual Recognition API の古いものを使っているので、顔ハメはうまく動きません)ものですが、いくつかの課題もありました。その1つが「スマホからの利用を想定していなかった」という致命的な点です。見た目でのスマホのウェブブラウザ最適化という意味では実現したつもりでしたが、想定外だったのは「スマホのカメラで撮影した画像の解像度が予想以上に高かった&今後は更に高くなることが想定される」ということです。

ある程度詳しい人には常識かもしれませんが、iPhone をはじめとする最近のスマートフォンのカメラはかなり高い解像度の写真を撮影することができます(特に設定を変更しない場合は、高解像度撮影が標準機能になっていることが多いです)。撮影した写真を低解像度にしてメールで送る、といったことは可能ですが、内部的には高解像度のまま保存されていることになります。これは1枚の写真画像のファイルサイズが非常に大きいということを意味しています。これは2つの点で問題になります。

1つはアプリケーションサーバー側の制約を受ける可能性があるという点です。例えば PHP を普通にインストールしたアプリケーションサーバーの場合、アップロードサイズは 2MB に設定されることが多いです。もちろんこの設定を変更できればいい話ですが、最近は PaaS などでミドルウェア設定を変更できないケースもあるので、そうなるとこの制約を受けてしまいます。

もう1つは API 側の仕様上の制約を受ける可能性です。このマンホライザーでは画像から顔の位置を認識・特定する必要があるのですが、その部分に IBM Watson の Visual Recognition API を使っています。この API の制約として現在は「画像は 2MB まで」という制約があるのでした。つまり上記のアプリケーションサーバー側の制約を取り除いただけでは解決にならないことも出てきてしまうのです。

上記で紹介した、以前作った PHP 版のマンホライザーにはこれら2つの課題があり、スマホからの利用を想定すると期待通りに動かないケースが出てきてしまいました。というわけで、ミドルウェアや設計段階から見直したマンホライザーを作り直すことにしたのでした。


上記2点を解決するため、まず PHP のアップロードファイルサイズ制約をうけないよう、アプリケーションサーバーは Node.js を使うことにしました。PHP から Node.js への移植を行いました。これによって 2MB を超える画像もアップロードできるようにしました。

また API 側のサイズ制約については、アップロードした画像を一旦内部的にリサイズし、API が実行できるレベルにまでサイズを減らしてから実行する、というロジックに変更することで対処しました。細かい点ですが、画像を小さくしてから実行するため、API からのレスポンスは「小さくなった画像に対する顔の位置」になります。アプリケーション側ではアップロードした画像のプレビューが表示されており、その画像にマンホールの位置とサイズを調整して「ハメる」わけですが、元の画像サイズに対するレスポンスにはなっていないので、その辺りも考慮する必要が生じます。

そんなこんなの変更を加えてできあがったのがこちらです:
https://manholizer.mybluemix.net/

2017020701

↑ちとズレてるが・・・


使い方は PC またはスマホのウェブブラウザでアプリケーションサーバー(https://manholizer.mybluemix.net/ とか)にアクセスしてください。で、「参照」ボタンをクリック:
2017020702

 

手元のローカルファイルシステムまたはフォトライブラリ等から画像ファイルを選択します。今回は「フリー素材アイドル」の Mika x Rika さんの画像を使わせていただきました:
顔4


この画像を指定して、しばらく待つと・・・
2017020703


こんな感じになりました:
2017020704


合成用マンホールのデザインとして使っているのは(マンホーラーであればおなじみの)東京都マンホールです:
2017020706


(2つの)顔の位置を識別し、うまく顔ハメになるようマンホールの位置と大きさが調整されて合成されています。またマンホールの色がピンクなのは「女性」であると認識されている様子です(男性の場合は青いマンホール画像を合成します)。また2人の上部に "-17" と表示されていますが、これは推定年齢でふたりとも「17才以下」であると推測されている、ということを意味しています(お二人の年齢は存じ上げませんが、全体的に日本人の顔は若く判定される傾向があるようです):
2017020705



なお、このサービスのソースコードはこちらで公開しています。興味ある方はご自身の環境でもどうぞ:
https://github.com/dotnsf/manholizerDemo


自分の環境に導入して使いたい場合の方法は README.md にも記述していますが、IBM Bluemix の Node.js ランタイムで使う場合であれば、まず Bluemix にログインして、SDK for Node.js ランタイムを1つ作成します(この時の名前を後で使います)。また Visual Recognition サービスインスタンスを生成し、その API KEY を取得しておきます(この値も後で使います)。

次に上記サイトからソースコードをダウンロード&展開するか git clone して、以下の2ファイルを編集します。

1つ目は settings.js です。この中の exports.vr_apikey の値に、上記で取得した自分の Watson Visual Recognition サービスの API Key の値を設定します(以下は API Key が abcdabcdabcdabcdabcdabcd であった場合の例です):
(settings.js)

: exports.vr_apykey = 'abcdabcdabcdabcdabcdabcd'; :

もう1つは manifest.yml です。この中を実際に運用するランタイムの情報に設定します。例えば eu-gb リージョンを使って、my_manholizer という名前のランタイムで運用する場合は以下のようになります(ng リージョンの場合、domain は変更せずにそのままで構いません):
(manifest.yml)

: domain: eu-gb.mybluemix.net name: my_manholizer host: my_manholizer :

この状態で cf コマンドを使ってアプリケーションを push すると、作成した Node.js ランタイム上にマンホライザーがデプロイされます:
$ cf push

IBM Bluemix を使わずに運用する場合は・・・ まあ普通に Node.js をインストールして npm install して使ってください(適当)。


IBM Watson の画像認識 API である Visual Recognition を使った類似画像検索サービスを作り、そのソースコードを公開しました:
https://github.com/dotnsf/imageSearchDemo


コードは Node.js で作りました。プロジェクト自体に(著作権フリーな)サンプル画像もいくつか含まれていますが、サンプル画像を置き換えて使うことでご自身が所有している画像を使った類似画像検索サービスにすることも可能です。

また基本的に Watson API は使いやすいものばかりだと思ってますが、このサンプルアプリもその特徴を最大限に活かして、単純に「学習させたい画像を用意すれば動く」ようにしました。細かな実装内容はソースコードを参照ください。


上記 github 上のリポジトリの README.md の中に使い方も(英語で)記載していますが、このブログでは日本語での簡単な使い方とカスタマイズについて紹介します。前提としてログインできる CentOS/RHEL のインスタンスに git と Node.js がインストールされている環境をご用意ください。また最終的なウェブアプリケーションは IBM Bluemix 上で動かすことにします(この場合は cf コマンドもインストールしておいてください)。異なるプラットフォームでも動くと思いますが、適宜読み替えてください。


準備

何はともあれ、IBM Watson の API を利用するためには IBM Bluemix のアカウントが必要です。まだアカウントをお持ちでない場合はトップページの「フリーアカウントを作成」ボタンから 30 日間無料で使えるトライアルアカウントを作成できます:
2017012601


Bluemix のアカウントでログインし、カタログ内 "Watson" カテゴリの "Visual Recognition" を選択して、この API を追加してください:
2017012602


なお作成時に "Free" プランを選択すると1日に 250 API call まで無料で利用できるプランになります。本格的に利用する場合はその下の "Standard" プランを検討ください:
2017012603


Visual Recognition API を作成後に、ダッシュボードから作成した同サービスを選択して、サービス資格情報から資格情報を確認します(なければ追加します)。そして "api_key" の値(下図ではモザイクにしています)がこの後必要になるのでメモしておきます:
2017012604


改めて github からソースコードを用意します。いくつかの方法がありますが、git が使える場合は git clone してください(または zip をダウンロードして展開してください):
$ git clone https://github.com/dotnsf/imageSearchDemo
$ cd imageSearchDemo

ソースコードを展開したディレクトリの直下に settings.js というファイルがあります。この中の exports.vr_apikey の値を先程メモした Visual Recognition API の API Key の値に書き換えて保存してください:
2017012605


他はそのままでも動きます。なお、exports.limit の値(デフォルトだと 5)はウェブアプリケーションで類似画像を検索した結果として、上位いくつまでの結果を表示対象とするかの数値です。学習させる画像の数などにもよりますが、必要に応じて書き換えて使ってください。

最後に、この後の学習時に必要な Node.js のミドルウェア: watson-developer-cloud を npm でインストールしておきます:
$ npm install watson-developer-cloud

この結果、プロジェクトのホームディレクトリ(imageSearchDemo)に node_modules というフォルダが作られていれば watson-developer-cloud の導入に成功したことになり、学習処理が行えるようになります。


画像の学習

最終的には類似画像を検索する仕組みを作りますが、そのためにはあらかじめ検索結果となる画像を学習させておく必要があります(学習させた画像の中から類似画像を探します)。そして学習のためにはある程度の枚数の画像が必要です。

上記ソースコードの public/images/ の中にはサンプルとして著作権フリーな画像が含まれています。これらをそのまま使って学習させることもできますし、手元にある画像で類似画像検索システムを作りたい場合はそれらを使うこともできます(その場合は public/images/ 以下のサンプル画像を全て削除した上で、ご自身の画像をこのフォルダ内に格納してください):
2017012606


そして、以下のコマンドを実行すると public/images/ フォルダ以下にある画像を Watson に学習させます(上記の settings.js ファイルの編集を忘れずに行っておいてください):
$ node learnImages.js
imagelearn_xxxxxx

学習が正しく行われた結果、画面には imagelearn_xxxxxx という文字列が表示されます。これが collection_id と呼ばれるもので、後述の Watson API Explorer などでこの API を実行する際には必要になります。またこのコマンドの実行後に setting.js の最終行に以下のような1行が追加されているはずです:
exports.vr_collection_id = 'imagelearn_xxxxxx';


ウェブアプリケーションとして利用

では学習した内容を使った類似画像検索ウェブアプリケーションを作成します。今回は IBM Bluemix 上のランタイムとして作成するので、SDK for Node.js ランタイムを1インスタンス作成します:
2017012607


アプリケーション名は適当にユニークなものを指定します。この例では dotnsf-imagesearch という名前のランタイムを作っています:
2017012608



合わせてソースコードの manifest.yml ファイルを更新します。具体的には name と host 両方の値を、実際に作成するアプリケーション名と同じものにします:
2017012609


ここまで準備できたらアプリケーションをデプロイします。cf コマンドを使ってログインし、プッシュします:
$ cf login -a http://api.ng.bluemix.net/
   :
   :

$ cf push

しばらくするとアプリケーションの転送とステージングが完了して、ランタイムが起動した旨のメッセージが表示されます:
2017012601


この段階でアプリケーションにアクセス可能です。PCかスマホのブラウザでアプリケーションの URL (上記の例だと http://dotnsf-imagesearch.mybluemix.net/)を指定して開くと、このような画面が表示されます:
2017012601


「参照」ボタンをクリックして、類似画像の対象となる画像を選択します。今回は学習データの中に野球ボールがあったので、それが検索できるかどうかを調べる目的で、学習データとは異なる野球ボール画像を指定してみることにします:
野球ボール


画像を指定すると画面が暗転して、類似画像検索が行われます:
2017012602


しばらくすると結果が得られて画面の暗転が戻ります。画面を下にスクロールすると学習データの中の類似画像候補が指定数(デフォルトでは5)表示されます。一番左に野球ボールが検索できているのがわかります。まあこんな感じのウェブアプリケーションサンプルです:
2017012603


画像を学習する部分は learnImages.js で実装しています。学習時に与えるメタデータ(画像検索の結果と一緒に取得できるテキスト情報)の内容を変更する場合はこのファイルをカスタマイズしてください。またウェブアプリケーション部分は app.js で、そしてウェブアプリケーションの見栄え部分は public/ フォルダ内の index.html に依存しています。見栄えを含めたウェブアプリケーションの挙動の変更はこれらのファイルを自由にカスタマイズしてお使いください(ソースコードは MIT ライセンスで配布しています)。



なお、API Key や collection_id を利用して実際に Visual Recognition API を実行する場合は、こちらの Watson API Explorer をお使いいただくのが便利です。仮に作成した collection_id を一度削除するような場合はこの画面から DELETE を実行いただくことができます:
https://watson-api-explorer.mybluemix.net/apis/visual-recognition-v3

また、Watson Visual Recognition API の関数リファレンスはこちらを参照ください:
https://www.ibm.com/watson/developercloud/visual-recognition/api/v3/



業務に関係して、ちょっとした画像アップローダーが欲しくなったので、IBM Bluemix でも動くようなものを作って一般化したものを公開します:
https://github.com/dotnsf/ImgUploader


PHP + MySQL + HTTP サーバー環境で動きます。Bluemix であれば PHP ランタイムClearDB試験提供の MySQL サービスを組み合わせた環境を想定しています:
2016061000


中身は非常にシンプルで、画像をアップロードして一覧で表示したり、プレビューしたり、というものです。画像データは BLOB 型にして MySQL 内に格納しているので、MySQL のバックアップを取ると画像データがバックアップされます。ここにアップロードした画像は URL でアクセスできるようになります。

アップロードに際しては PHP 設定の制約などを受けます。Bluemix 環境であれば最大 2MB です。PHP の設定を変更するなどしてください。必要に応じて認証を付けて運用してください。

その他、シンプルなので普通に使えると思っていますが、詳しくは GitHub の README を参照ください。


前回までの続きです:
Bluemix のビルドパックを作る(1/3)
Bluemix のビルドパックを作る(2/3)


このシリーズは3回に分けて IBM Bluemix 用のビルドパックをゼロから作成する手順を説明するもので、今回はその3回目です:
(1) ビルドパックを作る上で知っておくべきこと
(2) ビルドパックを作るための準備作業    
(3) ビルドパックを作成して、実際に動作確認
  ←今回はここ

前回までに、ビルドパックを作成する上で知っておくべき仕組みや制限事項についてをまとめ、実際に PHP + Apache HTTP Server 環境のビルドパックを作る上で必要になるモジュール(ビルドパック実行時の権限では作れないモジュール)の作成を終えました。

では今回はこれらのモジュールを使って、実際のビルドパックを作成し、実際に IBM Bluemix 上のランタイムとして起動し、動作を確認するまでを紹介します。

ではビルドパック作成環境にログインします。前回の作業は Ubuntu 環境下で行う必要がありましたが、ここからは Ubuntu である必要はありません(Windows や Mac, Ubuntu 以外の Linux でも構いません)。が、以下はそのまま Ubuntu を使って作業する前提(つまり前回の作業で出来上がったモジュールもローカル内にあるという前提)で紹介をします。 というわけで改めて Ubuntu 環境に SSH 等でログインします:
2015100901


作業用のディレクトリを用意します。今回は /tmp/buildpack というディレクトリを新たに作成して、この中で作業することにします:
$ mkdir -p /tmp/buildpack
$ cd /tmp/buildpack


上記作業内容の (1) で紹介したように、ビルドパックは3つのスクリプトを用意することで作成します。この3つのスクリプトを /tmp/buildpack/bin 以下に作成します。3つのスクリプトは Ruby などのスクリプト言語を利用することもできますが、今回は(個人的な慣れもあって)シェルを使って記述することにします:
$ mkdir bin
$ cd bin
$ touch detect
$ touch compile
$ touch release
$ chmod 775 detect
$ chmod 775 compile
$ chmod 775 release
$ cd ..


また、このスクリプト(具体的には compile スクリプト)の中では、前回の作業 (2) で作成した PHP と Apache HTTP Server 2つのモジュールを使うことになります。これらのモジュールをあらかじめビルドパックのディレクトリ内にコピー(または移動)しておきます。前回の作業 (2) と異なる環境で今回の作業をしている場合は、前回の環境からこれらのモジュールを SFTP などで転送して取得してください:
$ mkdir -p download/httpd/2.4
$ mv /app/apache-2.4.16.tar.gz download/httpd/2.4
$ mkdir -p download/php/5.6
$ mv /app/php-5.6.14.tar.gz download/php/5.6


また、PHP および Apache HTTP Server の動作設定とも言える php.ini と httpd.conf ファイルもあらかじめ用意しておきます:
$ mkdir config
$ vi config/httpd.conf
   :

$ vi config/php.ini
   :


これらのファイルの内容は皆さんが作成していただいても構わないのですが、今回は日本語を使う前提で、比較的緩めの条件設定で環境構築をするような内容にしています。具体的な内容は以下のリンク先と同じものです。これらと同じ内容で2つのファイルを用意/編集しておくと、かなりゆるゆるで、本番環境としてはともかく、開発テスト用に便利な PHP ランタイムができます:
https://github.com/dotnsf/php-apache-buildpack/tree/master/config

なお、注意事項として Apache HTTP Server が動作するポートは固定値ではなく、必ず環境変数 PORT から取得して起動させる必要があることに注意してください。したがって httpd.conf 内の Listen ディレクティブの指定は必ず以下の様な指定になっている必要があります:
  :
  :
Listen ${PORT}
  :
  :


あらためて、ここから3つのスクリプトを作っていきます。まずは detect スクリプトを作ります。このスクリプトはビルドパックの適用に適した環境が整っているかどうかを判断して、ふさわしいと判断した場合だけ次にすすめるようにする、というためのスクリプトです。 今回は PHP + Apache HTTP Server のビルドパックなので、選択肢としては「無条件にふさわしいと判断する」というのもアリですが、勉強目的もあるので多少強引に何らかの条件を付けるようにしてみましょう。

というわけで、今回の detect スクリプトでは
 ドキュメントルートに index.php ファイルが存在していたらビルドパック適用条件を満たしている、
 index.php が存在していない場合はビルドパックを適用しない

という条件判断をさせることにします。

また、これも (1) の中で説明していますが、detect スクリプトは実行ディレクトリ("cf push" を実行した時のカレントディレクトリ)を引数に受け取ります。この引数を使って、detect スクリプトを以下のような内容で編集します:

※ bin/detect の中身
#!/usr/bin/env bash
################################################################################
# bin/detect <build-dir>                                                       #
################################################################################

# ---------------------------------------------------------------------------- #
# ドキュメントルートに index.php が存在している時だけ有効                      #
# ---------------------------------------------------------------------------- #
if [ -f $1/index.php ]; then
  echo "My PHP Env"
  exit 0
else
  exit 1
fi


これで detect スクリプトによって、カレントディレクトリに index.php ファイルが存在している時だけ実行結果として 0 を返して compile スクリプト続行、存在してない場合は 1 が返されて処理が止まる、という実装にしました。


続いて compile スクリプトを作ります。ここがいわば「ビルドパックの本体」といえる部分で、実際のサーバー環境を、このスクリプト1つだけで構築していくことになるものです。

この compile スクリプトの中では前回の作業 (2) で作成したモジュールを使います:

※ bin/compile の中身
#!/usr/bin/env bash
################################################################################
# bin/compile <build-dir> <cache-dir>                                          #
################################################################################

# ---------------------------------------------------------------------------- #
# 変数を設定                                                                   #
# ---------------------------------------------------------------------------- #
BIN_DIR=$(dirname $0)
BUILDPACK_DIR=`cd $(dirname $0); cd ..; pwd`
BUILD_DIR=$1
CACHE_DIR=$2

APACHE_VERSION="2.4.16"
APACHE_PATH="apache"
PHP_VERSION="5.6.14"
PHP_PATH="php"

# ---------------------------------------------------------------------------- #
# ドキュメントルート(/app/www/)の設定                                          #
# ---------------------------------------------------------------------------- #
cd $BUILD_DIR

mkdir -p $CACHE_DIR/www
mv * $CACHE_DIR/www
mv $CACHE_DIR/www .

# ---------------------------------------------------------------------------- #
# コンパイル済みの Apache HTTP Server を展開                                   #
# ---------------------------------------------------------------------------- #
APACHE_DIR="${BUILDPACK_DIR}/download/httpd/2.4/apache-$APACHE_VERSION.tar.gz"
echo "-----> Bundling Apache version $APACHE_VERSION"
tar -xvf $APACHE_DIR

# ---------------------------------------------------------------------------- #
# コンパイル済みの PHP を展開                                                  #
# ---------------------------------------------------------------------------- #
PHP_DIR="${BUILDPACK_DIR}/download/php/5.6/php-$PHP_VERSION.tar.gz"
echo "-----> Bundling PHP version $PHP_VERSION"
tar -xvf $PHP_DIR 

# ---------------------------------------------------------------------------- #
# httpd.conf と php.ini を上書き                                               #
# ---------------------------------------------------------------------------- #
ls -al $BUILDPACK_DIR
cp $BUILDPACK_DIR/config/httpd.conf $APACHE_PATH/conf
cp $BUILDPACK_DIR/config/php.ini $PHP_PATH

# ---------------------------------------------------------------------------- #
# php のパスを設定                                                             #
# ---------------------------------------------------------------------------- #
mkdir -p bin
ln -s /app/php/bin/php bin/php

# ---------------------------------------------------------------------------- #
# Apache HTTP Server 起動スクリプト(boot.sh)作成                               #
# ---------------------------------------------------------------------------- #
cat >> boot.sh <<EOF
for var in \`env|cut -f1 -d=\`; do
echo "PassEnv \$var" >> /app/apache/conf/httpd.conf; done touch /app/apache/logs/error_log touch /app/apache/logs/access_log tail -F /app/apache/logs/error_log & tail -F /app/apache/logs/access_log & export LD_LIBRARY_PATH=/app/php/ext export PHP_INI_SCAN_DIR=/app/www echo "Launching apache" exec /app/apache/bin/httpd -DNO_DETACH EOF chmod +x boot.sh # ---------------------------------------------------------------------------- # # キャッシュディレクトリをクリア # # ---------------------------------------------------------------------------- # rm -rf $CACHE_DIR

最後に release スクリプトを作ります:

※ bin/release の中身
#!/usr/bin/env bash
################################################################################
# bin/release <build-dir>                                                      #
################################################################################

# ---------------------------------------------------------------------------- #
# boot.sh を実行するような YAML ファイルを生成                                 #
# ---------------------------------------------------------------------------- #
cat << EOF
config_vars:
    MYENV: myphp
default_process_types:
    web: sh boot.sh
EOF

これでビルドパックは完成です。作業した /tmp/buildpack 以下のディレクトリ/ファイル構成は以下の様な状態になっているはずです:
/tmp/buildpack/
 |- bin/
 |   |- compile
 |   |- detect
 |   |- release
 |- config/
 |   |- httpd.conf
 |   |- php.ini
 |- download/
     |- httpd/
     |   |- 2.4/
     |   |    |- apache-2.4.16.tar.gz
     |- php/
         |- 5.6/
              |- php-5.6.14.tar.gz


ではこのビルドパックを実際に使ってみます。が、そのためにはこのビルドパックをインターネット上の Git リポジトリに公開する必要があります。普段お使いの環境にオリジナルの Git 環境があればそこを使ってもいいのですが、今回は GitHub 上に公開しましょう。GitHub のアカウントを取得できていない場合は取得して、ログインまでを済ませておきます:
2015101002


画面右上の "+" 印をクリックし、"New repository" を選択して、新しいソースリポジトリを作成します:
2015101003


リポジトリの名前、説明(オプション)、そして Public リポジトリか Private リポジトリかを選択します。名前は何でもいいのですが、わかりやすいように "php-apache-buildpack" としました。説明はオプションで加えます。GitHub の有料アカウントであれば Private リポジトリを選ぶこともできますが、せっかくなので(というか、この後の話がややこしくならないように)Public を選択して公開しちゃいましょう。最後に "Create Repository" ボタンをクリックします:
2015101004


するとこんな感じの画面になり、ソースリポジトリが新規に追加できました。この時の URL (https://github.com/(ユーザー名)/(リポジトリ名)) を後で使うのでメモしておいてください。今はまだ中身が空ですが、ここに先程作ったビルドパックを転送します:
2015101005


改めて作業環境に戻ります。ここからは git クライアントによる作業になるため、git が必要です。git コマンド未導入の場合はコマンドラインで以下のように入力して git をインストールしておきます:
$ sudo apt-get install git

そしてビルドパックを作成したディレクトリ(/tmp/buildpack)に移動して、以下のコマンドを入力し、上記で作成した GitHub 上のリポジトリに転送します:
$ cd /tmp/buildpack
$ git init
$ git add .
$ git commit -m 'first commit'
$ git remote add origin https://github.com/****(先程メモしたリポジトリのURL)****.git
$ git push -u origin master
(GitHub 上のユーザー名を入力)
(GitHub のパスワードを入力)

転送完了後、改めてリポジトリの URL にブラウザでアクセス(まだ開いていればリロード)すると、作成したビルドパックが転送され、中身が入ったリポジトリになっているはずです。これでビルドパックの公開もできました:
2015101006



では最後にこのビルドパックを使って、実際に Bluemix 上にランタイムを1つ構築してみます。cf ツールをインストールしたマシンのあるディレクトリに index.php という名前で、以下のような phpinfo(); を実行するだけの内容のファイルを作成します:
<?php phpinfo(); ?>

また Bluemix 上にランタイムを1つ作ります。言語は(この後に変えるので)何を指定しても構いません。この例では dotnsf-php-20151010 という名前で作成していますが、実際には一意になるような名前を指定してください:
2015101001


そしてこの index.php ファイルが存在しているディレクトリから cf ツールで Bluemix 上にログインし、作成したビルドパックを指定してこのランタイムにプッシュします:
> cf login -a https://api.ng.bluemix.net/
(Bluemix のユーザー名を指定)
(パスワードを指定)

> cf push dotnsf-php-20151010 -b https://github.com/dotnsf/php-apache-buildpack.git
   :
   :
#0   running   2015-10-10 08:37:34 PM   0.2%   61.9M of 128M   163.5M of 1G


プッシュが成功したら、実際にこのランタイムの URL にアクセスして、phpinfo() の結果が表示されることを確認します。ちゃんと PHP のアプリケーションサーバーとして動いていることが確認できました:
2015101002


この中身をよく見ると、ビルドパックを作成した際に指定した内容で稼働していることが確認できます。というわけで元の(Bluemix の)PHP ランタイム環境ではなく、カスタマイズして作成した PHP ランタイムが動いていることも分かります:
2015101003


長い連載になりましたが、これで Bluemix のビルドパックを作って、公開して、実際に使ってみる所までが確認できました。PHP 以外のビルドパックを作る場合も、(権限の問題がないものであれば)この応用で作れると思います。是非色々チャレンジしていただけると嬉しいです。

このページのトップヘ