コミット毎に実行環境をビルドするoasisを書いた

Dockerの理解を深めるため、またGo言語の経験を積むためにoasisというツールを書いた。「とりあえず動いた」レベルの完成度であり、実用で使うにはもっと時間をかけて改善していく必要がある。

naoty/oasis

これはコミット毎の実行環境をdockerのコンテナとして提供するリバースプロキシだ。例えば、以下のようにoasisを起動する。

% oasis start \
    --proxy master.oasis.local:8080 \
    --container-host 192.168.99.100 \
    --repository github.com/naoty/sample_rails_app

このときhttp://master.oasis.local:8080にアクセスすると、oasisは以下のようなことを行う。

  1. --repositoryで指定されたリポジトリをgit cloneする。
  2. サブドメインで指定されたリビジョン、ここではmastergit checkoutする。
  3. リポジトリに含まれるDockerfileを使ってdocker buildする。
  4. ビルドしたイメージをdocker run -P -dして、コンテナを起動する。
  5. コンテナのホスト側ポート(例: 49154)を調べて、oasisへのアクセスを--container-hostで指定されたホスト上のコンテナ(例: 192.168.99.100:49154)にリダイレクトする。

f:id:naoty_k:20150409225939p:plain

実際にOSXで試す場合は、--proxy 127.0.0.1:8080のようなオプションで起動して、サブドメインの解決をPowに任せるといいと思う。

% cd ~/.pow
% echo 8080 > oasis

上のようにすると、http://*.oasis.devのように任意のサブドメインにアクセスできるようになり、8080ポートのoasisにポートフォワーディングされる。

所感

もともとは同僚の方が開発に携わっているmookjp/poolを見て、もうちょっとシンプルにセットアップできるようにしたいと思ったのがきっかけだった。実行ファイルをダウンロードして即実行できるようなものが理想だったので、Go言語を勉強しはじめこんなものを作ってみた。名前の「oasis」は最近ハマっているドミニオン・異郷に出てくるアクションカードであること、コンセプトのオリジナル実装であるpoolに雰囲気が似ていることから採った。

Go言語はとてもシンプルですんなり理解できたし、標準パッケージでリバースプロキシを簡単に実装できたため、短時間でここまで作ることができた。ちょっとしたツールを作るとき、これまではRubyでrubygemを書くようなことをしていたが、Go言語であればrubygemを書くほどのハードルの高さもなく、シンプルで生産性の高いコードを書いてそのまま配布することができていい感じだなと思った。

また、DockerについてもDocker Remote APIを触ってみたり、docker run-p-Pの違いを理解できたり、理解が深まったと思う。あんまり関係ないけど、サンプルアプリで使ったDockerfileはDocker Hubで配布された公式のrails用イメージを使ってるだけで、何も考えなくてよくて便利だった。