リクルート住まいカンパニー Tech Blog

ITのちからで暮らしをよくしたい、エンジニア・デザイナーが発信するTech情報メディア

お手軽PaaS Dokkuで検証環境を自動構築(1)

f:id:recruit-sumai:20170310185752p:plain

今回はWebアプリケーションの検証環境構築をDockerコンテナで省力化した事例を紹介します。

困っている事

特に新規事業系のWebサービス開発によくある課題として、動作検証環境の運用、構築に時間がかかり、地味にスケジュールの足を引っ張るという問題点があります。大抵のWebサービスの開発は以下のような複数個の環境(Webサーバ、DBサーバなどのサービス稼働に必要なインフラ一式)から構成されています。

f:id:recruit-sumai:20170124112432p:plain

例えば、デザイン変更、機能追加などの開発の流れを考えてみると、まずローカル環境で開発したWebアプリケーションは通常検証環境にデプロイされ、プランナー、QA担当などが確認してから本番環境へデプロイされます。ところが、困ったことにこの検証環境が”いくつ”必要かというと時期によって異なります。A/Bテストなどを考えるとデザイン案が複数あるケースは珍しくありませんし、機能追加が複数並行で走るケースは当たり前のようにあります。 そして前もって必要数を見積もって多めに作っておくとコストの無駄遣いですし、少なければチーム間の取り合いになってしまいます。

そういった場合は大抵はAWSなどのIaaSやPaaSでポチっとすれば10分もすれば完成・・・というというわけにも残念ながらいきません。通常、AWSなどのIaaS運用はインフラ専門チームの担当範囲になっています。開発チームとは別のクラウド運用チームにわざわざオペレーションを依頼する必要がありますので、どうしてもリードタイムがかかってしまいます。

また、リードタイム以外にも問題になりやすいこととしてコストがあります。通常、検証環境は本番環境に比べて使用頻度が低いことがほとんどのため運用コストはなるべく抑制したいものですが、最低限のスペックに抑えても複数の環境を構築するとどうしても費用が環境の数の分掛け算で必要になってしまいます。

そこで登場するのがDockerです。Dockerコンテナには色々なメリットがありますが今回は以下のようなメリットに着目しました。

  • メモリやCPUのオーバヘッドが少ないため、限られたリソースでも多数のコンテナが起動できる
  • メモリやCPUなどのハードウェアリソースを複数のコンテナ間で共用できる
  • Copy on Writeとkernel共用の仕組みにより仮想マシンに比べて非常に高速に起動できる

今回はこのようなメリットを活用したDockerベースのPaaS環境Dokkuを構築して、「いつでも」「必要な数の」検証環境を構築してみました。

Dokku(http://dokku.viewdocs.io/dokku/)の紹介 f:id:recruit-sumai:20170124112430p:plain と書かれているだけあってコア部分はわずか300行のBashスクリプトだけで書かれている超ミニHeroku互換プラットフォームです。プラグイン部分まで含めるとソースコードの行数は増えますが、全部Bashスクリプトで書かれています。そのため、何か挙動が不審だったり内部動作を確認したい場合は、ソースコードにecho文を追記するだけで簡単に内部動作が確認できます。

同種のPaaSプラットフォーム(CloudFoundary,Flynnなど)と比べてるとBashスクリプトで書かれているだけあって流石に複数ホストでのスケールアウトは不可能ですが、他のPaaSプラットフォームに比べて桁違いにシンプルで内部構造の理解や運用もとても簡単なメリットがあります。インストールもUbuntu/Debian系であればシェルスクリプト一発でインストール可能です。コンテナ上の処理系としてはHerokuのBuildPackかDockerhub上のイメージが使用可能ですので、面倒なサーバプロビジョニング(環境構築)も不要です。

 

内部構造

herokuと同じくアプリケーション開発者から見るとDokkuサーバはgitリポジトリのように振る舞います。通常のgitリポジトリと違うのはソースコードのpush完了後にフックとしてdokku本体が起動し、Dockerコンテナがビルドされることですことです。フック処理内でソースコードに以下のような処理を行ってWebアプリケーションとして公開します。

ビルドの流れはアプリケーションの種類によって異なります。

BuildpackベースのWebアプリケーションの場合(リポジトリ内にDockerfileが含まれていない場合)

  1. ベースとなるDockerコンテナをRun
  2. Buildpack(各言語毎のインタプリタ/コンパイラ/Webサーバなどの処理系をまとめて圧縮したもの)をコンテナ内へコピー
  3. アプリケーションのソースコードをコンテナ内にコピー
  4. コンテナ内のソースコードに対してJSのコンパイルや画像圧縮などデプロイにリリースに必要な後処理を実行

DockerベースのWebアプリケーションの場合(リポジトリ内にDockerfileが含まれている場合)

  1. ソースコードに含まれるDockerfileを元にコンテナのBuild
  2. リポジトリ上のソースコードをコンテナ内にコピー(Dockerfile内のCOPY文を使用)

上のいずれかの方法でコンテナのビルドが完了後

  1. dokkuホストサーバ側のNginx(リバースプロキシ)のバーチャルホスト設定(upstream)にビルドしたコンテナを登録
  2. コンテナを起動

でWebアプリケーションが公開されます。

今回はAWS EC2上に構築していますので、DokkuをインストールしたEC2と共にSSL証明書の発行とオフロードにALB(Application Load Balancer)とACM(AWS Certificate Manager)を組み合わせています。

 

 

インストール&はじめてのデプロイ

ではまずはdokkuサーバの環境構築と最も簡単なBuildpackベースのアプリケーションのデプロイを行ってみましょう。

dokkuサーバの環境構築

Ubuntu/Debian系のディストリビューションであればスクリプト一発で構築可能です。

$ wget -qO- https://raw.github.com/progrium/dokku/master/bootstrap.sh | sudo bash

これだけです。 サブドメインベースでアプリケーションをデプロイする場合はネームサーバへdokkuサーバのレコードを登録する必要があります。以下のようなA又はCNAMEレコードを設定してください

*.(アプリケーション公開時のベースとなるドメイン) → dokkuサーバのグローバルIPアドレス又はドメイン名

では簡単なnodeベースのWebアプリケーションをデプロイしてみましょう。 まずdokkuサーバ側にgit push時の認証に必要なユーザごとのssh公開鍵を登録します。この認証方式は通常のgitリポジトリと同じです。dokkuサーバへ何らかの方法で公開鍵をコピーしてから

$ cat id_rsa.pub | sudo sshcommand acl-add dokku (鍵の識別用の名前)”

を実行してください。

サンプルアプリケーションのデプロイ

次にサンプルアプリケーションを作成します。今回はnodejsのexpressフレームワークを使ってみました。 今回はdokkuサーバ自体のドメインはexample.org、作成したアプリケーションはdokku-sample-alpha.example.orgで公開するものとします。

$ express dokku-sample
$ cd dokku-sample
$ git init
$ git add .
$ git commit -m “initial commit”

gitのリモートリポジトリとしてdokkuサーバを登録します。その際、公開する際のサブドメイン名をパラメータとして指定します。

$ git remote add dokku dokku@example.org:dokku-sample-alpha

では改めてpushします

$ git push dokku master

今回は言語の処理系は今回は特に指定していませんが、コンテナのデプロイ時にpackage.json、composer.json、Gemfileなど各言語の特有のファイルを元に判別し、自動的に適切な言語のBuildpackがデプロイ時に使用されます。そのため面倒な仮想マシンの作成、プロビジョニングなどは不要です。うまくいけば最後にWebアプリケーションが公開されます。ポチっとブラウザで開くと、git pushしただけなのにもうwebアプリケーションが公開されました。

f:id:recruit-sumai:20170124112442p:plain

もちろん通常の開発フローを考えてみるとここで終わりではありません。大抵POや企画担当者に見せると「もうちょっとデザインをとりあえずいい感じに……とか」「ちょっと文字の色変えてみて新旧比べてみたい」とか言われますよね? そんな時は慌てず騒がず、新しいブランチを作ってソースコードを更新したらもう一個リモートリポジトリを追加します。リポジトリ追加時のパラメータを別に指定することで、同じアプリケーションでも別のサブドメインで公開することができます。今回はdokku-sample-blueのサブドメインで公開してみます。

$ git checkout -b font-blue
$ (ソースコードを編集してコミット)
$ git remote add dokku-blue dokku@example.org:dokku-sample-blue
$ git push dokku-blue font-blue:master

f:id:recruit-sumai:20170124112441p:plain

こんな風にgit pushするだけでブランチ別やコミット別にいくつでもWebアプリケーションの検証環境を作成することができますので、「検証環境が足りないのでQA担当がテストできない」「依頼して作ってもらうと時間がかかりすぎる」という事態を防ぐことができます。

今回は簡単なデプロイまでの流れを紹介しました。次回はもう少し複雑な内容とSuumoスマホサイトでの活用事例を紹介します。

  • Dockerfileを使ったデプロイ
  • ストレージコンテナとの連動
  • アプリケーションのデバッグ
  • gitリポジトリとの結合とSuumoスマホサイトでの活用事例

 

 

Git Logo by Jason Long is licensed under the Creative Commons Attribution 3.0 Unported License.