トップ 最新 追記

2015-09-06 [長年日記]

_ ItamaeとChefについての比較メモ

Chef Solo がオワコンというので気になってちょっと調べてみた感想。

背景

自分は Chef Solo を Vagrant と組み合わせて誰でも開発環境を作れるように、という目的で使っている。頑張ったのは 2013 年の話。

この時に頑張って以降はたまに pear package の install に失敗するとか、こまごました調整しかしてない。新しめの開発環境はわざわざ OS ごと仮想化しなくてもいいものを採用するので、古いものしかここにはない。これにプラスして Capistrano を導入して、commit されているものが deploy される、を実現した。今思うと遠い昔のようだ。(この春からは一部で GitHub + CircleCI + Heroku で自動 deploy にしている。)

production 環境の provisioning には使っていない。(特に変更を加えていないし、どうしても必要なものは手作業)

気になっていたこと

Itamae は Chef-like DSL というのは分かっていたけど、Chef-like だったらそもそもそんなにシンプルじゃないはずで、違いはどこにあるのか、といった辺りが気になっていた。

分かったこと

Chef は使い始めるのに必要なツールが案外多く、Chef を使いたいのに Knife を振りかざしてて、しかもこの Knife のサブコマンドがまた多くて、これ何やってるんだっけ感が強い。たぶん Rails の generator とかに影響受けてるんだと思うけど、さすがにボリューミーでつらい。

対して Itamae は itamae コマンドが叩ければok. ここのシンプルさはとても偉大だ。

resource を仮想化したあとにコマンドを叩く部分では Specinfra に依存している。この関係性は先にもっと大きく取り上げてよいように思う。自分の場合は Specinfra は Serverspec 用のものだと理解していたので、ちょっと悩んだ。

Specinfra がよくできているおかげで、Itamae で定義されたレシピは local でも ssh を通じた remote 上でも動く。remote には Itamae がインストールされている必要はない。

ということは Chef と同様のレシピがそのまま動くわけではない。Chef はレシピの実行にすべて Ruby が関わっているので、実行時にも Ruby の強力な記述力を活かせる。対して Itamae ではレシピの定義は Ruby だが OS にタッチする操作自体は Ruby で行っていない。ssh コマンド上で実行できる通常の OS のコマンドで実現する必要がある。

自分がそれを特徴的に感じたのは全 resource 共通で使える only_if, not_if 属性。

Chef ではここに文字列だけでなく Ruby の block も使える。Itamae はレシピ適用対象の OS で利用可能なコマンドを文字列で指定する。確かに。これしか方法はない。local でも remote でも使えるようにするための大きなトレードオフだと思う。

そうすると、複雑な条件を書こうと思うと sh script で使う test コマンドが活躍することになる。Ruby DSL で宣言的に記述できるという触れ込みがここで破綻する。ここは急に sh script の文脈になる。

新たに気になったこと

Itamae のドキュメント単体では node や attribute などの知識の補完が難しそう。そうすると結局 Chef のドキュメントに当たるのか、という問題がある。今後のドキュメントの整備が課題か。

まとめ

自分は provisioning の宣言的な記述には YAML より Ruby DSL の方がよいと思っている。Ansible の独自拡張 YAML は disposable infra にはいいかもしれないけど、変更を加えたり冪等性を確保するといった目的には使いにくいように思う。そして開発環境の provisioning は Docker をうまく使わない限りは disposable って難しいんじゃないかなと思っている。(開発環境だからこそ disposable じゃんていう指摘は正しいんだけど、ちょっとした変更のたびにゼロから環境作らなきゃいけなくてそれに長い時間掛かると、更新サボっちゃうでしょ?)

Itamae は Chef が持っている機能のうち DSL を切り出し、agent 的に動いてほしい部分は他のツールを併用して補うようにするなど、上手な割り切り方をしているように思う。何より itamae コマンド一つですぐに試せるのがサイコーによい。

古い環境とか Windows 対応は恐らく Chef の方にまだ一日の長がありそうだが、より新しめの環境にはマッチするのではないか。

ということで、次に新たに OS 丸ごと相手にしなければいけない時には Itamae を検討したい。

参考


2015-09-23 [長年日記]

_ Rails + Browserify + Mithril + cmsxで動くもん書いてみた

作った

これはなにか

  • GitHub の活用の幅を広げていくにあたって Issue のテンプレートがほしいと思ってたけど、最終的には URL を作る必要があるので、それを作るものを作った
  • Rails である必要はまったくなかったけど、裏側の作り込みを考えると組み合わせ的にはよく使いそうな感じが再現できて満足
  • ついでに Material Design てなんだろうと思って、あえて完全な gem を作りようのない Semantic UI を使ってみた

参考になるのはここら辺。

すでに似たようなのは当然世の中にある。

あとはテンプレートのノウハウを集めて作るだけ。こんなのは実は GitHub 時代に入る前の BTS と呼ばれてる時代から言われてたこと。いちばん最初にへーと思ったのはシックスアパートの以下の記事でした。

TypePadのテストで使っている3つのツール - Six Apart ブログ

近況

  • Heroku の multi buildpack を試してみたかった
  • 何やら最近は Rails の AssetPipeline が不人気らしい
  • Browserify Handbook を読んで npm のポリシーのよさ、そのよさに乗った開発をできるよさを知った
  • Mithril 本を読んでとりあえず何か書いてみなきゃと思った

これで夏休み前くらいからちまちまやってたことが一応区切れた。満足ぢゃ。

歴史

自分のスペック的なものなど。こういう経歴なのでこんなこと考えるんだな、こいつは、みたいな判断材料に使ってください。

  • Ruby と CoffeeScript が好きだけど、対レガシー PHP 戦歴もそれなり
  • JavaScript のフレームワークは Backbone.js, Angular1 をつまみ食い程度に
  • 一応 Jasmine でテストとか書けなくもない(今後は Mocha + power-assert にしたい)
  • Node.js は単なるユーザー。bower もタスクランナーも安定しないので敬遠してたらいい具合に npm に集約されそうでラッキー。
  • Rails は Rails 3 時代を中心に少々
  • SPA には縁がないが、Hybrid モバイルアプリでサクッと動くもんを作りたい、みたいなことは思ってる

感想

  • Heroku の multi buildpack は楽ちん
  • ブラウザのロードを契機とせずに watchify で回すのも悪くないかも

cf.

heroku/heroku-buildpack-multi

Mithril
  • Mithril は m.withAttr の名前以外はマジカルさも少なく、素直に書けてよい感じ
    • ただ、class も何もないっつーのは逆に覚えにくいので、API が少ないと言ってもやはりリファレンスが手放せない予感がちょっとしてる
  • 単に form の各要素を監視して値を計算して DOM を更新するだけなので AngularJS が日本で有名になりはじめの頃のサンプルに近く、あまり Mithril 向きじゃないかなと思ったけど、独自タグとかディレクティブがないので普通に JS でループ処理したり、割と楽に書けた
  • JSX クソきもいとか言っちゃってごめんなさい。CoffeeScript + MSX ( JSX for Mithril ) 快適です。

ただ、きっちりした型が(言語的な意味ではない)あった方がよい場合もあるので、AngularJS なんて不要とか言うつもりもないし、足りないものだらけなので、大きなアプリを書こうと思ったら、スケールはするかもしれないけど、実装力高くないとつらそうだなとは思う。

cf.

npm + browserify

きっかけは

俺の最近のRailsのJS開発環境を教えてやる - Qiita

で Sprockets で require するのはいいけど development 環境では GET の log が溢れかえって困るなーなんてことを思っていた時に上の記事を見かけたことだった。一応去年のうちに Browserify の名前は知っていたみたいだけど、この時まですっかり忘れていた。

  • npm の package 管理と npm run でやりたいことはだいたいカバーできてよい。まだ minify とかちゃんと見てないけど、最適化が仕事の中心ではないと理解しているので、概ね満足。
  • Browserify の transform とか、JS が変換前提になりつつある今、Sprockets だけでそれについていくのはやはり厳しい
  • 一方で Browserify もあくまで npm の世界観の一部をブラウザの世界に持ってくるためのものであって、asset 管理を全部任せようとするのは無駄に仕事を複雑にするのでよくない。AssetPipeline の方が楽できることもある。

Rails との組み合わせ方だけど、

Using Browserify with Ruby on Rails

を参考に、npm run で必要なコマンドを叩くだけにした。browserify-rails/browserify-rails よさげだったけど、結局 package.json に書くようなことを Rails の config に書くことになり、rails server が動いてブラウザでアクセスしないと browserify が動かないので邪魔くさいということが分かってやめた。

自分なりに工夫したのは Heroku の buildpack としては先に Node.js が動いて npm install + postinstall で browserify が動くようにしたことと、どうせ Heroku で Procfile を使うので、watchify は foreman で起動するようにしたこと。*1

cf.

AssetPipeline
  • 上手に gem になってる asset を扱わせた時の楽さは最強
  • 自分で asset を足していく場合、minify 済みの asset の扱いが苦手なので precompile 設定が外せず、面倒
  • require されてなくても対応拡張子に対してとりあえず変換が走るのうざい、vendor 以下に置いてしまえ
Material Design

いろいろ気づきはあったけど割愛。

Semantic UI

導入方法はともかく、記述量は増えるけど割と直感的に書ける気がする。リファレンス首っ引きにならずとも、たぶんこんな感じだよね?が通じるのは嬉しい。

twitter bootstrap のように標準の域に行くのは難しいかもしれないけど、なかなかよいものだと思う。

deploy時生成*2にこだわってたわけ
  • repos を小さく保てる
  • git grep 時に minify した JavaScript が引っかかるとか不幸すぎる
  • gem の読み込みとか node_modules からの deploy 時生成なら repos に入ってないからよい

実際には全部 deploy 時に生成するのは難しく、例えば Semantic UI は npm install 時に自分で build も行おうとするので gulp 必須で build 済みの asset をどう扱うかを考えざるを得ない。

今回、

  • .gitignore 対象ディレクトリ以下に asset を --force add
  • git grep --exclude-standard --no-index で探すと asset が引っかからない

ということを知ったので、repos の容量に影響しやすい font などを除いてこの形でいいような気がする。(font はでかいので CDN で解決できるならそれがベストなのではないかと思う)

まとめ

今回、Browserify と Mithril の二つをメインのキーワードに据えて、ちょっとイマドキなフロントのコードを扱ってみたいということで形にできたのはとても満足している。

次は Electron かな? いやーどうだろう。

*1 バックグラウンドに回ってしまうので終了が面倒くさくなるし、もし Un*x 的なプロセス管理とかに興味のない人にも開発に参加してもらおうと思った場合は間違いなくこの方がよい。

*2 rails の assets:precompile のようなもの