bash/zshとfzfでDocker関連コマンドの補完を行う方法

dockerコマンドはパラメータにコンテナIDやイメージIDを取るケースがあって入力が面倒です。 公式のbash/zsh用補完スクリプトを使うと各種ID類も補完できるようになるのですが、 Docker for Macをインストールするだけではそれらのスクリプトは有効にならないので、使い方を解説します。

また、fzfを使って候補のフィルタリングや複数選択を楽に行えるようにする方法についても説明します。

最終的にはこんな感じになります。

dockerとdocker-composeの補完スクリプト

Docker for Macにはbashとzsh用の補完スクリプトが同梱されています。

% ls -1 /Applications/Docker.app/Contents/Resources/etc/
docker-compose.bash-completion
docker-compose.zsh-completion
docker-machine.bash-completion
docker-machine.zsh-completion
docker.bash-completion
docker.fish-completion
docker.zsh-completion

適切に設定すれば下記のようにサブコマンドやイメージIDなどを補完できます。

Read More

Rails 5.2.0 で問題の起きるgem(simple_form, annotate)

Rails 5.2.0が正式にリリースされましたね。めでたい。

いつものことですが、2018-04-11現在、Rails 5.2.0だと正常に動作しないgemがあります。とりあえず見つけたものをメモしておきます。

simple_form

Rails 5.2.0 upgrade causes “Undefined method wrapper for SimpleForm:Module” error Issue #1568 · plataformatec/simple_form

Gemfileでsimple_formのバージョンを指定していない場合、railsのバージョンを5.2.0に上げてbundle updateしたらsimple_formのバージョンが3.5.1から1.4.1まで下がるという現象が起きていました。上記はそのために引き起こされるエラーです。

単にgemspecの要求バージョンが厳しかったみたいで、このブログを書いている間に 4.0.0 がリリースされて解決しました。

https://github.com/plataformatec/simple_form/blob/master/CHANGELOG.md#400

3.5系でバージョンをロックしている人は4.0.0を試してみましょう。

# Gemfile

# gem "simple_form", "~> 3.5.1"
gem "simple_form", "~> 4.0.0"

annotate

Annotate no longer works with Rails 5.2 models Issue #538 · ctran/annotate_models

./bin/rails annotate_models または ./bin/rails db:migrate など、モデルのアノテーションを更新する際に下記のようなエラーが起きる場合があります。

Unable to annotate app/models/author.rb: can't modify frozen String
Unable to annotate app/models/author.rb: no implicit conversion of nil into Array

暫定的な措置として、設定でインデックスに関する情報の記入を無効化すればエラーを回避できます。

diff --git a/lib/tasks/auto_annotate_models.rake b/lib/tasks/auto_annotate_models.rake
index 9088128..9c2f5d5 100644
--- a/lib/tasks/auto_annotate_models.rake
+++ b/lib/tasks/auto_annotate_models.rake
@@ -16,7 +16,7 @@ if Rails.env.development?
       'position_in_serializer'    => 'before',
       'show_foreign_keys'         => 'true',
       'show_complete_foreign_keys' => 'false',
-      'show_indexes'              => 'true',
+      'show_indexes'              => 'false',
       'simple_indexes'            => 'false',
       'model_dir'                 => 'app/models',
       'root_dir'                  => '',

他にも何か見つけたら更新していきます。

chef社のVagrant Boxがbento organizationに移行してた

Vagrantを使うときに、どこの馬の骨ともしれないboxは使いたくないので chef 社が公式にサポートしてるboxを使っていました。

# Vagrantfile
Vagrant.configure(2) do |config|
  # こんなの
  config.vm.box = "chef/centos-7.1"
end

8/27か28あたりに配布されなくなったようです。

https://vagrantcloud.com/chef

跡地でBentoというorganizationへ誘導しています。

https://atlas.hashicorp.com/bento/

BentoというのもChef社にメンテナンスされているプロジェクトで、PackerテンプレートでVagrantのbase boxイメージを作ることができます。

彼ら自身がchefをテストするためのboxイメージを作るためにも使っているとのこと。

https://github.com/chef/bento

今後はこんな風にBento boxを使うことにします。

# Vagrantfile
Vagrant.configure(2) do |config|
  config.vm.box = "bento/centos-7.1"
end

(おそらく公式の)BentoのTwitterアイコンがすごく弁当箱です。集中線がジワジワくる。

https://twitter.com/bento_chef

Vagrantでknife-zeroを使うためのベストプラクティス

Vagrantでknife-zeroを試そうとして挫折する人が多いらしいので、自分の考えるベストプラクティスを書いてみます。

追記:記事の一部を更新しました。詳細は末尾の更新履歴でご確認ください。

以下、Vagrantを開発環境で利用することを想定しています。

下記のドキュメントを参考にしました。

TL;DR

プライベートネットワークモードで立ち上げた2つのVMに、knife-zeroでレシピを適用する具体的な手順を説明します。

基本方針は下記の通り。

  • コマンドラインでのパラメータを極力減らす。
  • IPアドレスの記述は.envrcに集約して、その他の設定ファイルやコマンドラインでは環境変数を使う。

適切に設定ファイルを書けば、下記のような一連のコマンドでレシピの適用まで実行することができます。

% cd knife_zero_example
% direnv allow
% vagrant up
% bundle install --path=vendor/bundle --binstubs
% ./bin/berks vendor cookbooks
% ./bin/knife zero bootstrap $VAGRANT_HOST001
% ./bin/knife zero bootstrap $VAGRANT_HOST002
% ./bin/knife node run_list set host001.example build-essential
% ./bin/knife node run_list set host002.example build-essential
% ./bin/knife zero converge 'name:*.example' -a knife_zero.host

Read More

技術ブログのためのHexoのテーマ Ingenuous をリリースしました

先日ブログエンジンをHexoに移行したのですが、その際に下記のページのテーマをひと通り試してみました。

しかしどれもしっくりこなかったので、デフォルトのテーマ Landscape をベースにして自分好みのものを作りました。

変更がそれなりの分量になったので、Ingenuousと名前をつけてリリースすることにしました。

kwhrtsk/hexo-theme-ingenuous

欲しい機能を追加したり、スタイルを部分的に自分好みに修正したりしています。 基本方針は「自分の技術ブログに必要十分な機能とスタイル」です。

主な追加機能・変更箇所は下記の通り。

  • モバイルの画面で、コードブロックにより多くのコードが表示されるように修正
  • サイドバーにAboutウィジェットを追加
  • モバイルのナビゲーションメニューにサイドバー(モバイルでの表示時は画面下部へ移動)のアイテムへジャンプするリンクを追加
  • 投稿ページにシェア数を表示
  • 記事内にTOCを表示する機能追加(front-matterでtoc: trueを指定)

あとは過去記事のページネーションなど細かい修正をいくつか。

オリジナルのLandscapeはMIT License、IngenuousもMIT Licenseです。

RailsのエラーモニタリングツールErrbitのChefレシピ

4/17に大阪で開催されたRailsの勉強会でLTしてきました。

自分の発表資料をちょっと加筆修正したものを以下に公開しました。

テーマはRailsのエラーモニタリングです。

通知先はSlackという前提で、 exception_notificationというgemで直接Slackに通知する方法と、 New RelicやAirbrakeといったWebサービス経由で通知する方法、 Errbit というOSSのAirbrakクローン経由でSlackに通知する方法を紹介しました。

ErrbitはHerokuの無料枠で運用することが可能で、詳細なセットアップの情報が日本語でも見つかります。

Errbit - Railsアプリの本番エラーをherokuで管理、メール通知する【無料枠】 - 酒と泪とRubyとRailsと

今回はHerokuを使わずにオンプレやAmazon EC2のようなIaaSに自分でセットアップする方法を検討しました。

まずErrbitをセットアップするChefのレシピを探してみたのですが、見つかったものは対応しているErrbitのバージョンが古く、サポートもUbuntuのみでした。

errbit Cookbook - Chef Supermarket

自分はCentOSも好きなので、2015-04-17時点の最新のErrbitに対応していて、かつUbuntuとCentOSのどちらもサポートしているものを作成して公開しました。

errbit-server Cookbook - Chef Supermarket

今回はコミュニティクックブックを多めに使ってやってみました。大まかな構成は下記のとおりです。

  • コミュニティクックブックでやっていること
    • mongodbのインストール
    • rbenvとruby_buildのインストール
    • ruby 2.2.2のインストール(attributeで変更可能)
    • Errbitのチェックアウトと初期化
      • applicationクックブックを利用
      • application_rubyはマイグレーションでbundlerのrakeを使おうとせずにエラーになるのでスルー
    • ErrbitにバンドルされているUnicornをservice_factoryでサービス化(SysV or Upstart)
    • Unicornのlogrotate
  • 自前で追加した分
    • Errbitのデプロイ先のディレクトリレイアウト
    • Errbitの初期化処理(rake errbit:bootstrap)
    • ErrbitのUnicornを起動するためのラッパ作成
    • Errbitの設定値のための環境変数をattributeで設定する仕組み

Vagrantで動作を確認するための手順をsampleディレクトリに置いています。下記のバージョンの組み合わせで動作を確認しています。

  • OSX Yosemite
  • Ruby 2.2.2
  • Vagrant 1.7.2
  • VirtualBox 4.3.26
  • CentOS 6.6 or Ubuntu 14.10

CentOSで試すのであれば、ターミナルで下記のようなコマンドを入力すると、最終的に http://192.168.33.10:3000/ でローカルVM上のErrbitにログインできます。

Read More

Sidekiqのコードに潜む愉快なメソッドたち


少し前にRails4.2のActiveJobのバックエンドについて調べました。

Resque、SidekiqからSucker PunchまでActiveJobのバックエンドについてひと通り調べてみた

このときSidekiqのコードを読んで、Celluloidによるアクターモデルで並行処理を実装していることを知りました。 ちょうどScalaやErlangでアクターを使う方法を調べていたところだったので興味がわき、Celluloidを利用したアプリケーションのサンプルとして読んでみることにしました。

その時見つけた愉快なメソッドを紹介します。

今回読んだSidekiqのバージョンは3.3.3です。

注意事項

  • 本エントリはSidekiqやアクターの解説記事ではありません。
  • 記事に機種依存文字が含まれています。
    • OSXのChromeとFirefox、iOSのSafariとChromeでのみ表示を確認しています。
    • iOSのブラウザではGithubから引用しているコードの一部が化けます。

Read More

Rails 開発をサポートするChrome拡張 Rails Panel の機能と仕組み

7 must have Development Gems to install on every project

この記事を読んでいて、Rails PanelというChrome拡張を知りました。

Rails Panelでできること

デベロッパーツールにRailsというパネルが追加されます。 このパネルでは、ページリクエスト単位で下記のような情報を表示することができます。

  • Breakdown: 処理時間の内訳(ActiveRecord, Rendering, Other)
  • Params: コントローラから参照できるparamsの内容
  • ActiveRecord: そのリクエストを処理する際に発行したSQLと処理時間
  • Rendering: ビューテンプレートごとの描画時間

要するに rails server の標準出力(あるいは log/${RAILS_ENV}.log)の情報を見やすく表示してくれます。

Read More

Resque、SidekiqからSucker PunchまでActiveJobのバックエンドについてひと通り調べてみた

ActiveJobのバックエンドと、永続化先としてRedisが好まれる理由

Rails 4.2で、ActiveJobというクラスが導入されました。

これ以前より、Railsで非同期処理を行う際にはResqueやSidekiq、Delayed Jobなどが広く使われていましたが、 ActiveJobはジョブを記述するためのインタフェースを抽象化して、 ジョブの実装を変えること無くジョブランナーを切り替えることを可能にするものです。 なおActiveJobにおいては、バックエンドを指定しなければジョブは非同期実行しようとしても即座に実行されます。

Rails 4.2.0時点では、ActiveJobのバックエンドとして以下のページにある9つのいずれかを使用できます。

ActiveJob::QueueAdapters

  • Backburner
  • Delayed Job
  • Qu
  • Que
  • queue_classic
  • Resque 1.x
  • Sidekiq
  • Sneakers
  • Sucker Punch

ちなみにRuby ToolboxのBackground Jobsというカテゴリの上位3つは、Resque、Sidekiq、Delayed Jobでした。この3つがよく使われている印象です。

The Ruby Toolbox - Background Jobs: Save jobs in a queue and process them later wihout blocking your current thread

特にResque、Sidekiqは、ジョブの情報を永続化する先としてRedisを必須としています。

情報の保存先ならActiveRecord(RDBMS)でも良さそうなものですが、あえてRedisを必須としている理由は何だろうか考えてみました。

ぱっと思いつくのは、「キューにジョブが積まれた」というイベントをワーカーへ伝えるための手段として、 RedisのPub/SubBLPOP/BRPOPのようなメッセージング機構を使うのが簡単で都合が良かったのではないか?ということです。

バックエンドにMySQLのようなRDBMSを使う場合、普通に考えるとワーカー側はジョブを保存したテーブルをロックしつつポーリングしないといけないのでスケールしなさそうだし、 RabbitMQのようなメッセージングサービスを用いるのと比べて、RedisであればRailsエンジニアは元々better memcachedとして使用しているケースが多いので導入のハードルが低いです。

というわけで、このエントリではResque、Sidekiqの2つについてはRedisのメッセージング機構を使っているかどうかを確認しつつ、 ActiveJobのページに挙げられている9つのプロダクトについてジョブ情報の保存先を調べてまとめてみようと思います。

9つの中で特にSucker Punchはジョブの保存先もワーカープロセスの起動も必要とせずに非同期処理を行えるので、簡単に作りたいならおすすめです。詳細は後述。

Read More