IBM Bluemix 上のランタイムとして使えるビルドパックを自分でゼロから作る、ということに挑戦してみます。今回は作業は行わず、その仕組とか概要の説明になります。 とはいえ、ここで知っておかないと作ったり、うまく動かなかった時の調整に困ったり、一度作ったものを自分なりに再カスタマイズする際に手間取ったりすると思ったので、一応知っておくべきことをまとめておきます。

予定としてはこんな感じで、3回に分けて説明するつもりです:
(1) ビルドパックを作る上で知っておくべきこと ←今回はここ
(2) ビルドパックを作るための準備作業
(3) ビルドパックを作成して、実際に動作確認



ビルドパックとは?

ビルドパックとは Bluemix 上で動作するランタイムの実行基盤を準備するための仕組みです。元々は Heroku 用に開発されたカスタマイズのための仕組みで、CloudFoundry では V2 から採用されています。Bluemix のランタイムメニューからも、GitHub 上に公開されたコミュニティー提供のものも、多くのビルドパックが公開され、利用可能です。


ビルドパックの環境

Bluemix 上に作成されるランタイムには Ubuntu Linux が使われます。2015年10月時点では Bluemix のスタックは Ubuntu 14.04.2 trusty (x86_64) です。

ビルドパックで用意した環境は、最終的にこの Ubuntu サーバー上にコピーされて動くことになります。つまり、Ubuntu 14.04.2 上で動くようなものを作る必要があるわけです。

ビルドパックを構築する作業の中で C のコンパイルなどの作業を行いますが、それらは Ubuntu 14.04.2(x86_64) 上で動くようなモジュールにする必要があります。作ったビルドパックの動作確認時の手間などを考えると、ビルドパックのカスタマイズは事実上 Ubuntu 環境上で作業する必要があります。

というわけで、次回以降で実際に行う作業は全て Ubuntu 14.04 環境上で行います。この環境を用意しておく必要があります:
2015101001



ビルドパックの構成

ビルドパックは detect, compile, release という3つのスクリプトから構成され、これらが順次実行されます:
スクリプト説明
bin/detectアプリケーションの構造をチェックして、導入可能な構成か(次に進んでいいか)をチェックする
bin/compileランタイム環境を作成する
bin/release起動時のコマンド等を作成する


注意点として、これら3つのスクリプトは vcap という一般ユーザー権限で実行される、ということです(セキュリティ上の制約)。なお、この vcap ユーザーには sudo 権限はありません。つまり、これら3つのスクリプトは一般ユーザー権限で実行できるようなものにする必要があります。管理者権限が必要な作業はこれらのスクリプト実行の前に全て終わらせておく必要があり、これらのスクリプトの中では一般ユーザー権限で実行できるものしか使えません。

具体的には、例えば apt-get install などはこれらのスクリプトの中では使えません。ただし wget であれば使える、などです。

したがって例えば Apache HTTP Server をビルドパックに含めるには、bin/compile スクリプトの中で Apache HTTP Server を apt-get install して・・・というわけにはいきません。予め Apache HTTP Server のソースファイル一式を入手しておいて、コンパイルして Ubuntu 上で動くバイナリを作っておいて、それを bin/compile スクリプトで実行ディレクトリにコピーして使う、という流れになります。共有ライブラリなどを使う場合にも同様の注意が必要です。

また、各スクリプトで生成したり、配置したりするファイルは "/app/" 以下に配置するようなスクリプトにする必要があります。"/tmp" や "/var/tmp" 以下には永続性保証がありません。

これら3つのスクリプト、それぞれについて詳細を以下で紹介します。


detect スクリプト

このスクリプトはビルドパックの実行条件を判断するためのスクリプトです。プッシュしようとしている内容が、このビルドパックで用意された環境向けの内容としてふさわしいかどうかを判断し、(例えば PHP ランタイムなのに PHP ファイルが含まれていないなど)ふさわしくないと判断したら compile には進みません。

このスクリプトには引数が1つ渡されて実行されます。渡される引数はプッシュされるアプリケーションのパスです。

そしてその引数を参照して(しなくてもいいけど) detect スクリプトが実行され、ビルドパック実行にふさわしいと判断したら標準出力に 0 を出力します。ビルドパック実行にふさわしくないと判断したら標準出力に 1 を出力します。detect スクリプトは 0 か 1 を標準出力に出力して完了します。


compile スクリプト

実際のビルドパック環境を構築するスクリプトです。実際に動くアプリケーションサーバー環境を作り上げるスクリプトとなり、いわば、ここがビルドパックの肝になる部分です。

このスクリプトは detect スクリプトの出力結果が 0 だった場合のみ実行されます。

このスクリプトには引数が2つ渡されて実行されます。第一引数はプッシュされるアプリケーションのパス、第二引数はキャッシュディレクトリのパスです。detect スクリプトとは違い、標準出力への内容がルール化されているわけではありません。

繰り返しになりますが、このスクリプトは一般ユーザー権限で実行されます。なので、例えば HTTP サーバーを導入する場合、apt-get install では導入できません。あらかじめソースファイルからバイナリを生成しておいて、compile スクリプト内では生成済みバイナリを実行パスにコピーする、といった形で環境構築を行う必要があります。


release スクリプト

アプリケーション起動時の動作を指定するスクリプトです。

このスクリプトには引数が1つ渡されて実行されます。渡される引数はプッシュされるアプリケーションのパスです。

このスクリプトの実行結果は、以下の様な YAML フォーマットで出力する必要があります。最後の commandLine の部分にアプリケーションサーバーを稼働させるためのスクリプトを記述します:
config_vars:
 name: value
default_process_types:
 web: commandLine



今回の内容はここまでです。ビルドパックを作る上での制限というか、制約というか・・・は理解できたでしょうか? 普通に Bluemix を使う上では知らなくてもいいことが多かったと思いますが、ビルドパックという低レベルなカスタマイズを行おうとすると、こういった知識も必要になってきます。ちょっと面倒に感じるところがあるかもしれませんが、勝手に変なスクリプトが実行されることのないよう、現状のような(比較的制限の大きな)仕様になっているのでした。

次回は、実際にビルドパックをゼロから作るための、その準備段階を紹介する予定です。 実際の作業はプログラミングというよりも「どれだけ Linux に詳しいか」を痛感するような内容になります(苦笑)。がんばって着いてきてくださいっ!

(2015/Oct/15 追記)
続きはこちら