読者です 読者をやめる 読者になる 読者になる

Dockerで非エンジニアでも開発環境を上げ下げできる、mirageというツールを作りました

docker mirage golang

いやー今年もISUCONの予選参加募集がはじまりましたね! 昨年は出題側だったので胃が痛かったですが、今年は参加側ですので大変楽しみにしております。@acidlemonです。

Docker使ってますか?

さてみなさん、Docker使ってますか? 使ってる? 使ってない? ぼくは使ってませんでした。えー今どきBlue-Green Deploymentやってないの? Immutable Infrastuctureじゃないの? と言われそうですが、世の中にはいろんなしがらみとかもあってなかなか簡単にエイヤーでコンテナに移行できるわけでもないのは皆さんなんとなく感じているのではないでしょうか。

とはいえ、最近これだけ話題になっているDockerですので、そろそろ使ってみたいなぁ…ということで、まずは開発環境をDockerで上げられるようにしました。

Dockerでコンテナを作るときには2つのアプローチがあります。

一つはアプリケーションコンテナ。ステートレスなアプリケーションだけを入れて、永続ストアはコンテナの外におく。新しいアプリケーションをデプロイするときは新しいコンテナを作って上位のロードバランサをそちらに向けて、古いコンテナを破棄するというBlue-Green Deploymentのための使い方。

もう一つはサービスコンテナ。アプリケーションやストレージミドルウェアなどなど、サービスを動かすために必要なものを全部入れて作るコンテナです。これを作るメリットはどちらかというと「気軽に捨てられる」という感じなので、新しいバージョンをデプロイしたコンテナを手元や開発サーバで動かしてテストして、使い終わったらすぐコンテナを破棄するみたいな使い方です。

今回はサービスコンテナで開発中のサービスを気軽に立てられるようにしました。具体的にはワイルドカード付きのサブドメインをDockerが走っているホストに全部向けて、表においたnginxからコンテナにReverse Proxyします。

DockerfileにはMySQLとかRedisとかをインストールして、そのあとプロジェクトのリポジトリをcloneして、carton installして動作に必要なものを全部準備した状態のDockerイメージをビルドしておきます。RUNで実行するシェルスクリプトには、git pull、環境変数GIT_BRANCHを取ってきてgit checkout $GIT_BRANCH、そのあとcarton installで実行環境を最新化してProcletを使ったスクリプトを実行して必要なミドルウェア全部とWebアプリを立ち上げるようにしました。

ただ、これには一つ問題がありました。それは「エンジニアじゃないとコンテナ立てられないのでオレが忙しいのは変わらない」ということです。チームにはディレクターやデザイナーもおり、マスターデータやバナーなどのグラフィックをgitにコミットしてくれるのですが、結局それをデプロイしたコンテナを立てるという作業をエンジニアがやらないと、彼ら/彼女らが開発サーバで実地確認できないのです。

ということで、それを解決するためにmirageというツールをGoで書きました。前置きがちょっと長かったですね。

mirageのご紹介

mirageの機能と特徴はこんなかんじです。

  • RESTおよびWebのインタフェースで、Dockerコンテナを起動/停止することができます。その際、
    • サブドメインを指定して、コンテナへのリバースプロキシを提供します
    • gitのブランチ名を指定して、特定のブランチでサービスを構成できます
      • RUNで起動するプログラムから環境変数GIT_BRANCHにアクセスして指定したブランチ名を取得できます

インストールについてはREADMEにも書いてありますが、ビルド済みバイナリがありますのでこちらをご利用いただくのが便利です。簡単にどういう感じで動くのかという構成図をご覧ください。

mirage概要図

図がフルスタックすぎてよくわかりませんね! ということで使い方で機能を説明したいと思います。

まずDockerfileを作って、docker buildでイメージが出来てるという前提からスタートします。また、REST API、Web Interfaceどちらを使っても同じ機能を利用できますが、説明が面倒なのでここではcurlで説明します。

コンテナの起動

あなたはトピックブランチでの開発を終え、開発サーバにデプロイして実際に動かしてみることにしました。トピックブランチの名前はfeature/cool-cool-coolです。さぁ、cool.myapp.example.net でfeature/cool-cool-coolブランチをデプロイしたコンテナにアクセスできるようにしましょう。

curl http://docker.myapp.example.net/api/launch \
  -d subdomain=cool \
  -d branch=feature/cool-cool-cool \
  -d image=myapp:latest

これで、コンテナが起動します。mirageは起動したコンテナをinspectしてコンテナのIPアドレスを調べます。起動後、cool.myapp.example.com にアクセスすると、mirageは接続を起動したコンテナへリバースプロクシします。

プロキシするポートはmirageの設定ファイルで指定可能です。例えば、mirageの8080ポートで待ち受けている通信をコンテナの5000ポートへリバースプロクシするといったことも可能です。また、複数のポートを待ち受けて、それぞれ指定したポートへリバースプロクシすることもできます。

コンテナの停止

feature/cool-cool-coolブランチの動作確認が終わったらもうコンテナはいらないので、破棄しましょう。

  curl http://docker.myapp.example.net/api/terminate \
    -d subdomain=cool 

これで、コンテナが停止します。停止したあとはcool.myapp.example.comにアクセスしても、mirageが404を返します。


はい! 非常にざっくりした説明でした!

いやーしかしこれはあれです。毎回curlでこんなに長いコマンドを叩いているのは大変です。そんなわけで、IRC botやhubotなどを利用している人は、botにcurlを叩かせればよいですね! もともとREST APIはそれ用に用意しています。bot作るのめんどいなーという人は、Web Interfaceで使ってみてください。

ちなみに、コンテナを起動するときのDocker Imageは基本的にほぼ固定になるとおもいます。そういう使い方であれば、mirageの設定ファイルでデフォルトのコンテナを指定できます。そうなれば、サブドメインとブランチを指定すればスポーンと上がってくるので、コンテナを起動するのがますます楽になりますね。

実際に活用するまでにDockerfile作ったりドメイン設定を変えたりみたいな感じでいろいろ仕込みが必要ですが、仕込んでしまえばあとは楽に使えます。

とはいえこの記事だけで使うのはちょっと大変かもしれません。実際に使い始めるまでのチュートリアルは別途書こうかなぁと思っています。なお、一刻も早く使ってみたいけどよくわからんという人は、8/29、8/30に開催のYAPC::Asia 2014で @acidlemon を捕まえて根掘り葉掘り聞いていただければと思います。それではYAPCの会場でお会いしましょう!

カヤックではYAPCでビール飲むのが好きなエンジニアや、Goでツール作ったりするのが好きなエンジニアを募集しています!