トップ 最新 追記

2016-05-15 [長年日記]

_ Dokku試してみた

Heroku でやるにも規模が小さいけど、sleep 時間だけが課題になるアプリが欲しくなってきたので、とにかく運用、管理に手間を掛けずに似たようなことができないか調べてみたら Dokku というものを見つけたので、現時点でのメモ。

現状は

  • まだ production では使っていない
  • 対象バージョンは 0.5.6

書いてる人のやったことや背景。

  • とにかくサーバ管理に手間を掛けたくない
  • Docker には興味なくはないけど、そこ突っ込む時間はない
  • Vagrant + Ubuntu 14.04 で試してみた
  • 最初の Web UI での設定ミスってもあとでなんとかなる
  • Dokku を試すには Vagrant と ssh の理解があれば Docker はそんなに分かってなくても大丈夫っぽい

間違ってたらツッコミお願いします。

メモなので、これ読んで勉強になるかっつーとたぶん厳しいです。

Dokku

Dokku - The smallest PaaS implementation you've ever seen

Docker で mini-Heroku のようなものを作るから Dokku という名前なのかな。

Linux 上に Docker と Heroku Buildpack を使って git push だけでアプリの実行環境を作って deploy することができるもの。

アプリは複数動かすことができ、Nginx を router として使っている。port 変更と Virtual Host の二つの方法で 1ホスト上の複数のアプリへのアクセスルートを確保している。

Vagrant + Ubuntu 14.04 で試した話は割愛

面白い部分はない。

ざっくり所感

Heroku のような手軽さは欲しいがそんなに本格的なコストを掛けるほどのものではない場合は VPS + Dokku というのも一つの方法のように見える。日本リージョンのサーバ(さくらとか)なら Heroku よりレスポンスは早いし。(Heroku の Tokyo リージョンは手軽さのうえにおもてなしが揃ってる Heroku Enterprise のものなので、極小規模アプリだけの話だとさすがに選択肢に入れられない。)

ただし、Heroku はよく分からないから Dokku を試してみよう、みたいなのは勧めない。絶対に逆がいい。Heroku を知っていれば Dokku の可能性を感じることができるし、限界も容易に想像がつく。

気づいたこと

Dokku 0.3(2013-12), 0.4(2015-09)辺りで大きな変更が入っている。ちょっと前の話を前提にすると全然噛み合わない可能性あり。

自分の場合は Docker にはあんまり興味ないので生々しい部分は触れずに興味を持った点などを挙げてみる。

  • heroku コマンドのように外から管理コマンドを実行することはできない
  • Docker環境というかサーバ管理の最初の課題はストレージ
  • Webアプリでストレージを生々しく使いたくなるのはログ、画像などのアップロード機能、DBMS
multi buildpacks 対応

以前は plugin で実現していたようだが、0.3 のどこかで追加されたっぽく、0.5.6 の時点では何も設定せずに multi buildpack が使えた。

ただし 2016-05 時点での Heroku のようにきれいな UI があるわけではなく、multi buildpack が出たての時のように

.buildpacks

というファイルを用意する方式でイケる。

DBMS

DBMS は小規模なら plugin で直接ホスト上に構築しても問題なし。あとは backup などを自動化しておけ。

それでまかなえないなら本格的な DBMS サービスを追加して別ホストにした方がいいと思うけど、それならアプリケーションサーバも見直した方がいいと思う。

cron

cron は dokku user の cron をそのまま使う。ただし cron の管理しにくさはみんな気づいてるわけだ。

webhook plugin はあるので、UI が欲しい場合はそっち使ってもいいかも

nickstenning/dokku-webhooks: A dokku plugin for triggering external webhooks.

One-off process

Dokku - The smallest PaaS implementation you've ever seen

dokku run と dokku enter がキモなのかも。

log

logsprout というものがある

gliderlabs/logspout: Log routing for Docker container logs

ので、外部のサービスに投げちゃうのがよさそう。

Papertrail - cloud-hosted log management, live in seconds

とか。

GitHub Flow

手軽なものほど自分以外も deploy できてほしい。

pull-req が扱えて CI/CD サービスと組み合わせて GitHub Flow でいいかな。

その他諸々メモ

最初に Web UI でセットアップできるのは便利なようで、特に最初は何を入れるのが正しいか分からないので、間違えた時にどうしたらよいかを中心に設定ファイルの場所をメモ。

Virtual Host と DNS

0.5.6 のタイミングから dokku.me ドメインが登録され、正引きで 10.0.0.2 が返ってくる。古いドキュメントや「試してみた」系の記事ではこれは押さえられていないが、この IP アドレスは以下のように使える。

Vagrant で試す際にはゲストOSに 10.0.0.2 でアクセスできるように(例えば HostOnly IP を)設定しておくと、Virtual Host でアプリを動かしやすくなる。

要は Dokku 本家の動かしている xip.io みたいなもん。

※ もちろん 10.0.0.2 の 1つしか IP アドレスがないので同時に動かす Dokku ホストは1つしか作れないし、たまたま自分のネットワークでこの IP アドレスが使えない可能性はある。

したがってこれでもう hosts や xip.io とはおさらばさ、とは言えない。そういうノウハウもあった方がよい。

関連リンクはここ。

基本の場所
/home/dokku
ssh

Web UI で入れる deploy 用の key はここに入る

/home/dokku/.ssh/authorized_keys

Vagrant でのテストならこいつに vagrant の insecure_private_key の public key を与えても ok

Virtual Host 方式かどうかを後から切り替える

node.js - Dokku change settings after install - Stack Overflow

以下のファイルが関係している。

  • /home/dokku/VHOST
  • /home/dokku/ENV

Virtual Host 方式でない場合は以下の設定が行なわれている状態。

config:set NO_VHOST

こうなっていると deploy 時に Nginx の port がランダムに割り当てられる。

したがって後から Virtual Host 方式にするにはアプリに対して以下のように変更するとよい。

  • `config:unset NO_VHOST`
  • `config:set DOKKU_NGINX_PORT=80`
Buildが通らない場合

Dokku の実行にはメモリ 1GB 以上推奨で、それ未満の場合は swap を追加しろとドキュメントにある。

Dokku - The smallest PaaS implementation you've ever seen

その他

New Relic

Application Performance Management & Monitoring | New Relic

サーバ管理はしたくないけどサービスの状況は知りたい。そんな時に便利なのが New Relic なのは皆さんご存知の通りですね。

管理UI

あるにはあるけど、セットアップに手間が掛かると本末転倒なので、まだ試してない。

aramirez92/quais: Web UI Manager for dokku

SMTPとか

SendGrid には無料範囲はないので AWS SES とかかな? SMTP 用意するのもアリだけど monitoring が面倒で、どうしたものか。

Nginx でやる? さすがになぁ。

結論出てない。Google Apps あるならそっちに任せるでもいいのかな。

あと plugin チェック

おまけ

Buildpack という考え方は PaaS ではポピュラーらしく、これには慣れておいた方がよさそう。

ひしめき合うOpen PaaSを徹底解剖! PaaSの今と未来

Dokku を知ったのはこの資料でした。感謝。


2016-05-21 [長年日記]

_ Kanazawa.rbでCIハンズオンをやったよ

または Kanazawa.rb meetup #45 で無双してきたよ!の話。

Meetup #45 - Kanazawarb

今回はタイトルを「はじめてのC☆I」にした。要するにテーマは Continuous Integration である。

最初の段階ではそんなに深い意味は考えてなくて、単に meetup #45 はもくもくじゃない回をやるタイミングだったのでどうしようかなと考えた時に、手持ちのネタとして比較的ライトに開催でき、かつハンズオンで時間稼ぎできるんじゃないかという気持ちで考えていた。(実は)

今回はそんな meetup #45 にいたる準備と開催中に感じていたことをつらつらと書いてみる。

CIを体験するだけに集中できる内容に

ハンズオンについてはとにかく「テーマ以外のことを気にしなくて済むように」に集中して考えた。これは以前 Heroku ハンズオンをやって、Windows で Rails の環境を用意するのが大変、Windows で Git + SSH の環境を作るのが大変、PostgreSQL の環境を用意してなかった、など「HerokuというよりはRailsに手こずった」印象が残っていたためである。

ということで

  • GitHub アカウントだけ事前に用意してもらう
  • こちらで用意したリポジトリを各自が fork
  • GitHub アカウントで CircleCI にログインしてリポジトリと紐付ける作業
  • CircleCI 側で自動でテストが走るように元のリポジトリで細工しておく
  • リポジトリの中身はだいたいみんなが分かるだろう HTML, JS, CSS だけのもの

という設計にした。

※ 当初 45 分程度を予想していたのだが、余裕を見て 1時間に設定したところ見事に 45 分で終わってしまい、最後に急遽自動テストの環境をその場で用意することになるとはまったく予想していなかったが…。

これで「言語の環境がどうとか」「テストコードがどうとか」「テストの書き方がどうとか」全部すっ飛ばせるでしょ、という読み。

用意したのは以下のリポジトリ。

wtnabe/todomvc-vanillajs: forked TodoMVC (VanillaJS version)

内容はなんでもよかったんだけど、あとで中身に興味を持っても意味のあるものにしておきたかったので、いっとき流行った TodoMVC の中の VanillaJS バージョンを用意した。

(実は最初に自分を盛り上げるためにやったのはこのリポジトリを本家の TodoMVC のリポジトリから分離する処理を自動化することだった笑)

あっ、そもそもCIってなんだっけ

しかし、じゃあいざ人前で CI で喋るとぞとなった時に、自分の中にちゃんとした CI 像がないことが分かってきた。なんとなく自動で何かが処理されて、結果の通知が Slack で受け取れて…いやいや待て待て、通知の話は CI の必須要件じゃないよな。そもそも CI を入れて本当に嬉しいことって何?みたいな疑問が次から次へと出てきて、タイムテーブルは埋まるけどほんとにこんなんでいいのか?と不安になってあれこれ調べていた。

そんな時見つけたのが ThoughtWorks の CI に関するページだった。

Continuous Integration | ThoughtWorks

とてもよい内容だったのでこれを使ってイントロを喋った。曰く

チェックインごとに自動化されたビルドによって検証され、チームは問題を早く検出することができるようになる。

これですよ、と。問題は早く発見できた方がその解決も早くなる。とてもシンプルだけど大きなメリットだと自分は感じたので何はともあれ最初にこれを話した。

あとは戦場のリアルな話も、GitHub Flow や Continuous Deployment の話も役者が揃っている。ぼくは安心してピエロになってみんなが手を動かしやすい準備と雰囲気を作るだけ。

GitHub Flowの話からworkflow話が盛り上がった

当日いちばん盛り上がったのは、CI ハンズオンでも CI 話でもなく、実は workflow の話だった。(もちろん CircleCI ハンズオンもそれなりにウケたんですよ!)

GitHub Flow は pull-req を中心において branching をシンプルに、ガンガンリリースしていこうという workflow だ。

これを紹介し、pull-req の画面上で CI の様子が確認でき、master へ merge することで CI サービスから deploy できることを示してからが、がぜん盛り上がった。

  • そうは言ってもいきなりリリースは怖い
    • staging を用意して自動でそっちにリリースすることもできますよ
  • いやいや、やっぱ develop ブランチはあった方がよいのでは
    • 開発期間やチームの大きさにもよるかもしれないですね
  • 話ずれますけど、レビューのキューが詰まってコンフリクトが頻発しています
    • branch の寿命が長すぎる、変更の影響範囲が広すぎる、チーム内のレベル差が大きすぎるなどあるかもしれませんね
    • そこだけ別 branch を用意した方がいいかもね

自分が GitHub Flow を採用しようと思った理由

当日は整理できていなかったのでうまく話せなかったが、あとで思い出したので改めて書き起こしてみる。

自分が(ほとんどのコードで)GitHub Flow を採用しているのは何より

制約が単純でツールがよくできているから

である。

それ以前は

に紹介されている、いわゆる Git Flow と呼ばれるものを採用していた。まずは develop ブランチを用意しましょう、ってやつ。

Subversion 時代の感覚(branch の寿命が長い開発)にはマッチしていて個人的には割とよいなと思っていたんだけど、バージョン管理初心者にはいきなり local だ remote だ用語がバンバン増えていく中で branch の意味とか細かく覚えてられないのが正直なところだったらしく、すぐにはリリースできない、あるいは明日リリース予定のものが remote の develop に突っ込まれて hotfix がリリースできなくなるなど、変な混乱が収まるまでしばらく時間を要してしまった。すぐにリリースしない branch が他の branch を block してしまう、ということが直感的に理解できないようだった。

結局、master と develop が一致していないといろいろ面倒になってしまうのであれば、そもそも develop は要らないのでは?と思っていたところ、GitHub Flow を知り、これがぴったりマッチしたのでそれに飛びついた、というのが実情である。決して GitHub Flow はレビューしやすい、とかそこまで積極的によりよいプラクティスを求めていたわけでもない。とにかくシンプルなので変なことが起きにくいのが最大の利点だ。

(これはバグがリリースされにくいという意味ではなく、メンバーの理解度が高くなくても変なことが起きにくいという意味。残念ながら。バグは最悪 rollback すればなんとかなるので。重大さにもよるけど。)

改めてCIとworkflowについて思ったこと

自分の場合は CI と CD ( Continuous Deployment ) は少なくともうちの(比較的小規模な)Web 開発においてはリリース担当者などの blocker 要素を減らしつつある程度の品質を確保するために不可欠な要素になっている。

以前は全員が capistrano を叩けるように教育もしたけど、今はそれも不要になった。こうして極力軽量なプロセスにしないと回らない現実と戦うのが至上命題だからこそ CI と GitHub Flow がマッチしているのだけれど、ここにこだわってやってる現場は(少なくとも近辺には)あまりないかもしれない。参加者の中ではやはりもっと branch の寿命も長いとか、そもそもコードをクラウドに乗せられないので SaaS な CI に頼るのは難しいという人が比較的多かったように思う。

そういう現場はもちろんそれなりに多いだろうし、そこで GitHub Flow を入れないなんてクソですよという気は毛頭ない。ただちょっとこの地域の Web 界隈の、特にフロントエンド方面の人を煽るつもりはあったけどね。

CI と GitHub Flow でリリースサイクルを小さく速く回すためには、当然だけどフロントエンドの人も Git を使ってコミットし、レビューする人が GitHub 上で pull-req を merge するのが最も合理的だ。特に若い人にはそれくらい当たり前にこなせるようになってもらいたいという願いは込めていた。

ヘビーウェイトなプロセスはそれに見合う重さを持つプロダクトに適用してしかるべきであって、ライトに回せるはずの開発をヘビーに回す必然性はないと自分は考えている。それは単なる不勉強だろう。そういう気持ちは込めてある。採用するかしないかは現場次第だし、現場現場でプロセス、ワークフローはカスタマイズが必要だとは思うが、伝統的な人力ベースの重たいワークフローは昨今の多くの現場で割りに合わないのではないか、というのが自分の意見だ。まして制作よりの小さな Web 開発であればなおさらである。

あなたの現場には変な待ちとか無意味なブリッジとか妙に属人化したタスクとか謎の○○職人とか、ありませんか? それって本当に必然性あるの?

コードをクラウドに乗せられない問題と本当のコストと最初の一歩

最後はややポエミーに。

当日の timeline でよく流れていたのはソースコードを GitHub に置けないというものだった。(紹介した SaaS が GitHub にしか対応していないとか、結構多かったからだろう。)GitHub は CI の必須要件じゃないので、紹介したツールにこだわらずに目的を達成することができれば別に GitHub にコードを置く必要はないと思う。とは言え、時間短縮をするためにはよくできたツールに乗っかった方がいいよ、というのは長いこと自分の価値観の中心にあるものだ。

例えば実際に CI を導入しようと思ったら誰がその準備をすることになるだろう。だいたいはエース級の「様々な仕組みをよく理解して適切なコミットを作れる人」がやると思う。その時、エースがどれだけ時間を使えますか? いやいや、そんなところに時間使うなんて無理だし他のやつじゃ CI なんて分かってないし無理だよ、ってことになっちゃわない? それって要は最初から無理って決まってるってことだよね。

最近、変えるための準備に時間が必要なのではなく、変えることに時間が掛かるから変えられないのではないか?ということを時々考えている。そのルールは本当に合っているの? ルールが目的化していない? 大事なことはなんなの? 流行りのツールを取り入れることは目的じゃないけど、だからといってこれまでのルールが本当に理に適っているとは限らないよね。現時点では仕方ない、って判断は普通によくある。過去においてもこの「現時点」はいくつもあったはずだ。だったら見直さなきゃ。

すぐにいっぺんに全部変えるのはそりゃ無理だと思う。でもこの問題に取り組もうとしている人は、問題を適切に分解して解いていくことを、それをソフトウェアで実現する人たちなんだよね? ちょっとでいい、すぐにできることでいい、変えられることから変えていけばいいじゃん。

さーて、次は何をかましてやっかね。