VagrantとChefでNode.jsの開発環境を構築する手順その2

『JS+Node.jsによるWebクローラー/ネットエージェント開発テクニック』のサンプル実行環境の構築について。

一つ前のエントリでnvmクックブックを使ってNode.jsの開発環境を構築する手順をまとめたが、いくつか不便な点があった。

  • sudoでnode、npmを使うために設定ファイルの編集が必要
  • npmパッケージのインストールは別途コマンドを打つ必要がある

上記の点を解決できないかと、nvmクックブックを使うのをやめて、nodejsクックブックで環境を作り直してみた。そもそもNode.jsのバージョンを変更する場合は、仮想マシンそのものを作り直すので敢えてnvmを使う必要もないと思う。

npmモジュールのインストールに合わせて、freetype、fontconfig、mecabなど必要なツールのインストールも追加した。

手順の差分を記載する。

Berksfile

カスタムクックブック

Vagrantfile

感想

  • nodejsモジュールでは、Node.jsのバージョンを指定することはできないらしい。今回実行したところ、v0.10.36がインストールされた。
  • npmパッケージのインストールをレシピにまとめることができた。

iconvモジュールのインストールで「‘REPLACE_INVALID_UTF8’ is not a member of ‘v8::String’」というエラーが発生した。理由はよくわかっていないが、事前にnpm install -g npmを実行することでエラーを回避することができた。

VagrantとChefでNode.jsの開発環境を構築する手順

『JS+Node.jsによるWebクローラー/ネットエージェント[開発テクニック]』のサンプルを試すためにNode.jsの開発環境を作った。本の紹介に従ってVagrantを使用し、CentOS6.5の環境を作った。ゲストOSの設定を手動でポチポチするのは面倒だったので、プロヴィジョニングにChefを使用した。

基本的には以前に書いたVagrantとChefでRailsの開発環境を構築する手順と同じ。主な変更点は以下の通り。

  • knife soloを使わない。
  • Chef soloではなく、Chef zeroを使う。

利用したツールのバージョン

  • ゲストOS: OSX El Capitan 10.11.2
  • VirtualBox 5.0.10 r104061
  • Vagrant 1.7.4
  • Chef Development Kit Version: 0.10.0

事前準備

VagrantとVirtualBox、ChefDKをインストールする。

Vagrantのプラグインをインストールする。

プロジェクトのディレクトリを作成する。

クックブックの配置

クックブックのリポジトリを作成する。

Berksfileを作成する。

berkshelfを実行する。

カスタムクックブックを作成する。

metadata.rbにdepends 'nvm'を追加する。

default.rbを編集する。

vagrant up

Vagrantfileを作成する。

Vagrantfileを編集する。

  • boxはpuphpet/centos65-x64を使用する。
  • provisionerにchef_zeroを指定する。

vagrant up。

しばらく待てばプロヴィジョニングと仮想マシンの起動が完了する。

動作確認

仮想マシンにログインしてnvmとnodeがインストールされていることを確認する。

感想

  • Chef関連の手順は、あまり情報を追っていないこともあり、正直よくわからない。
  • Chef soloとChef zeroの違いがよくわからない。
  • chef/centos-6.5のboxがなくなっていて驚いた。

現在時刻の美人時計の画像URLを返すHubotスクリプトを作った。

現在時刻の美人時計の画像URLを返すHubotスクリプト「hubot-bijin-tokei」を作った。

仕様は以下の通り。

使用イメージ

使用イメージ。

インストール方法

Hubotのプロジェクトディレクトリで以下のコマンドを実行する。

external-scripts.jsonに以下の内容を追加する。

メモ

システムのタイムゾーンに関わらず、日本時間の時刻を返す。HerokuでHubotを動かすことを想定している。Herokuのタイムゾーンを変更するのが面倒だと思ったので、スクリプトで日本時間を返すようにした。

[local]は、URLに含まれるアルファベットを指定することが基本であるが、日本語の名称を指定することも出来る。日本語の美人なうは、respondではなくhearで設定しているため、Hubotへの呼びかけでなくても反応する。IMEがONの時に、IMEをいじることなく、そのまま美人なう、北海道などと入力することを想定している。

リポジトリ

Githubでソースコードを公開している。

VagrantとChefでRailsの開発環境を構築する手順

手元のMacBookにRailsの開発環境を構築した。手順と調べたことを記録しておく。

構築する環境について

開発用の仮想環境を作り、ゲストOSでRailsを動作させる。仮想環境の管理にはVagrantを使用する。ゲストOSの環境構築はChefを使用して自動化する。開発時のファイルの編集は、Vagrantの共有フォルダ機能を使用してホスト側で行うものとする。

ホスト側の環境はOSX Yosemite 10.10.2である。

ゲストOSにはCentOSを使用する。Rubyはrbenvで管理する。システムにインストールするgemはbundlerのみとし、railsを含めその他のgemはすべてbundlerで管理する。

環境を構築するに当たって、事前にウェブの関連情報を探してみた。ヒットする情報の量は多いが、内容がまちまちなようである。同じことをするにも複数のやり方があったり、ツールのバージョンによってやり方が異なったりするようである。今回は、できる限り現時点の最新の公式情報に則り、公式のツールを使うことを目標とする。

Vagrantのインストールと設定

VagrantとVirtualBoxをインストールする。VagrantはHomebrewで、VirtualBoxはHomebrew Caskでインストールできる。

Vagrantのプラグインである「vagrant-omnibus」をインストールする。vagrant-omnibusは、ゲストOSのChefの状態を確認し、指定したバージョンのChefをゲストOSに自動的にインストールするか、または指定したバージョンにアップデートしてくれる。

プロジェクト用のディレクトリを作る。

vagrant initで、Vagrantfileを作成する。

Vagrantfileを編集する。Vagrantfileの設定方法は、Vagrantの公式ドキュメントを参考にする。

config.vm.boxについて。どこからBoxを調達するのが良いかという点であるが、公式ドキュメントの解説では、ATLASのDiscover Vagrant Boxesページが案内されている。ATLASは、Vagrantの開発主体であるHashiCorpが運営するサービスであるらしい。また、config.vm.boxに、<ユーザ名>/<Box名>の形式で設定を記述した場合、同名のBoxがローカルに存在しなければ、自動的にATLASのサイトを検索して、該当するBoxをダウンロードするようになっている。

今回は、Discover Vagrant Boxesを「centos」で検索した時に最もダウンロード数が多い「chef/centos-6.5」を使うこととする。

config.omnibus.chef_versionは、vagrant-omnibusのための設定である。chef_version = :latestは、最新版のChefを表す。

config.vm.provision "chef_solo"以下に、Chef Soloによるプロビジョニングの設定を記述する。設定方法は、公式のドキュメントが詳しい。cookbooks_pathに適用するクックブックの保存先ディレクトリを指定する。add_recipeで実行するレシピを指定する。

Chef関連ツールのインストール

Chef関連のツールをインストールする。Chefは関連するツールが様々あり、多くはgemを使ってインストールすることができる。Chefの公式の案内によると、これからChefの利用を始める場合には、Chef Development Kit(ChefDK)を利用することが推奨されているようである。

ChefDKには、Chef、Berkshelf、Test Kitchen、ChefSpec、Foodcritic、Chef client、Knife、Ohai、Chef zeroが含まれている。それらのツール群と、それらのツール群が依存するRubyの処理系をパッケージにまとめたものが、Chef Development Kitであるらしい。

ChefDKは、Homebrew-Caskでインストールすることができる。

ChefDKには、knife soloが含まれていない。ChefDKのインストール後に、knife-soloを個別にインストールする。chef gemコマンドを使うことで、ChefDKの処理系に対してknife-soloをインストールすることができる。

クックブックの準備

knife solo initでChef関連ファイルのひな形を作る。

Berksfileを編集する。Berksfileは、サードパーティのクックブックを、依存関係を解決しつつまとめて管理するツールであるBerkshelfの設定ファイルである。Berkshelfで取得できるクックブックは、Chef Supermarketで探すことができる。

berks vendorで、必要なクックブックをcookbooksディレクトリ配下に取得する。

knife cookbook createで、新しいクックブックのひな形を、site-cookbooks配下に作成する。

新しく作成したクックブックのメタデータ(site-cookbooks/base/metadata.rb)とレシピファイル(site-cookbooks/base/recipes/default.rb)を編集する。

メタデータには、依存するクックブックをdependsで指定する。今回は、rbenvクックブックが提供するリソースを使用するため、depends 'rbenv'を指定する。

Chef Supermarketのrbenvクックブックは、rbenvを自動的にインストールしてくれる。また、カスタムクックブックでruby本体とgemをインストールするための、rbenv_rubyリソースと、rbenv_gemリソースを提供してくれる。詳しい使い方はChef Supermarketのrbenvのページで解説されている。rbenv_rubyを使って、Ruby 2.1.5をグローバルにインストールし、rbenv_gemを使って、bundlerをインストールする。

chef/centos-6.5のBoxは、デフォルトではssh以外のほとんどの通信を遮断するように設定されている。ホストのブラウザからゲストOSのRailsにアクセスするために、ここではiptablesを無効にすることとする。

vagrant upからrails sの実行まで

事前の準備が完了したので、ここでvagrant upする。

初回のvagrant up時に、自動的にプロヴィジョニングが実行される。起動とプロヴィジョニングが完了したら、ゲストOSにログインし、プロヴィジョニングが正しく完了していることを確認する。

次にRailsアプリを作成するが、その際にプロジェクトのディレクトリとして/vagrantを使用する。/vagrantは、ホスト側のVagrantfileが存在するディレクトリと自動的に共有設定されている。そのため、/vagrantに保存したファイルは、ホスト側から編集することが可能になる。

/vagrantディレクトリに移動して、Gemfileを作る。

Gemfileを編集する。

bundle installを実行する。

rails newを実行する。Gemfileを上書きするか確認されるので、Yesを選択する。

rails sで動作確認用のサーバを起動する。Rails 4.2で、ゲストOSのRailsにホスト側から接続する場合、-b 0.0.0.0を指定しなければ接続することが出来ない。Rails 4.2のリリースノートによると、Rails 4.2からrails serverのデフォルトホストが0.0.0.0からlocalhostに変更されたことが原因であるらしい。

ホスト側のブラウザで「http://localhost:4000」にアクセスする(Vagrantのポートフォワードでホストの4000をゲストの3000にフォワードしているため)。Railsのトップ画面が表示される。

以上で開発環境の構築は完了である。以降、rails grails sなどRailsのタスク実行、マイグレーション、Gemfileを更新した時のbundle install、テストの実行は、ゲストOS側で実行する。また、バージョン管理はホスト側のプロジェクトディレクトリでgit initして、基本的にはホスト側で行う。

ホスト側でもrails sできるか、試しに実行してみたが、already initialized constant APP_PATHというワーニングが発生して、起動することは出来なかった。ゲストOS側、ホスト側を意識せずに、どちらでもRailsのタスクが実行できたら便利なのにと思う。

その他の話題:vagrant provisionが失敗する

vagrantのプロヴィジョン機能について。

私の環境では、初回のvagrant up時のプロヴィジョンは成功するが、2回目以降のvagrant provisionvagrant reload --provisionは、cookbookがゲストOSに正しく転送されず、必ずCookbook (hoge) not foundのエラーが発生する現象が起きている。

本来、cookbooks_pathで指定したパスが共有フォルダに設定されなければいけないところが、初回のvagrant up時以外は、該当のパスが共有フォルダに指定されないためにエラーが発生しているらしい。このエラーが発生した場合、.vagrantディレクトリ以下の.vagrant/machines/default/virtualbox/synced_foldersを削除して、vagrant reload --provisionを実行すると、正常にプロヴィジョンすることができる。

ひとまず上記の方法で回避はできているが、根本的な原因と解決策は不明である。誰かわかる人がいたら教えてください。

非Railsの環境でActiveRecordのマイグレーションを利用する方法

非Railsの環境でActiveRecordのマイグレーションを使う方法を調べた。

まず、ディレクトリ構造を作成する。db/migrate/ディレクトリ以下にマイグレーションファイルを配置することとする。config/ディレクトリ以下、database.ymlにデータベース接続の設定を記述する。log/ディレクトリ以下、migration.logにマイグレーション実行時のログを出力する。

database.ymlにデータベース接続の設定を記述する。

マイグレーションタスクを実行するためのRakefileを作成する。

db/migrate/ディレクトリ以下にマイグレーションファイルを作成する。マイグレーションファイルのファイル名は、001_create_tests.rbというようにマイグレーションの順番を表す数字で始める。また、ファイル名とマイグレーションファイル内のクラス名を合わせる。

rakeを実行すると、マイグレーションが実行される。rake VERSION=xでバージョンを指定したマイグレーションを実行する。また、rake rollbackを実行すると、ロールバックが実行される。rake rollback STEP=xで、ステップ数を指定したロールバックを実行する。

参考にしたウェブサイト

以下のウェブサイトを参考にした。

ブログのデザインテーマをTwenty Fifteenに変更した。

ブログのデザインテーマを「Twenty Fifteen」に変更した。Twenty Fifteenは、2015年のWordPressの公式テーマである。併せて、いくつか設定の変更を行った。

DISQUSのレイアウト修正

テーマをTwenty Fifteenに変更したところ、コメント管理システムであるDISQUSのレイアウトが崩れた。「AlexDresko.com」の「Fixing Disqus in the WordPress Twenty Fifteen theme」という記事を参考に、レイアウトを修正するための設定を行った。

レイアウトを修正するために、CSSを編集する必要があった。上記の記事に記載されている通り、Jetpackをインストールし、Jetpackの機能を利用して、CSSの編集を行った。

AmazonJSのインストール

Amazonのアフィリエイトリンクをきれいに表示するために、AmazonJSをインストールした。AmazonJSのインストールと設定の方法は、「EasyRamble」の「WordPressでアマゾン・アソシエイトを簡単設定!Amazon JSプラグイン」という記事を参考にした。

Google Adsenseの配置

記事の末尾とサイトのフッタにGoogle Adsenseの広告を表示するために、content.phpfooter.phpを少しだけ編集した。Twenty Fifteenがレスポンシブデザインであるため、Google Adsenseの広告サイズも「レスポンシブ」を使用することにした。iPhone5のSafariで表示した際に、レイアウトが崩れることがなくなったので良かったと思う。

その他

PS Auto Sitemapを使用して、サイトマップを作成した。

Jetpackのインストールに伴い、WP Social Bookmarking LightMarkdown on Save Improvedの機能をJetpackの機能に置き換えることにし、両プラグインを削除した。

Railsプロジェクトでwill_paginateを使用する手順

Railsのプロジェクトでページネーション用のライブラリ「will_paginate」を使用する手順をまとめました。

will_paginateの使用手順

  1. Gemfileを編集する
  2. paginate用のデータを準備する
  3. ヘルパーメソッドを記述する

1. Gemfileを編集する

Gemfileにgem 'will_paginate'を追加します。

Gemfileを編集後、bundle installを実行します。

2. paginate用のデータを準備する

コントローラの中でページネーション用のデータを準備します。ページネーション用のデータはpaginateメソッドを使って作成します。

ページごとの件数を指定する

ページごとの件数を指定する場合は、paginateメソッドに:per_pageオプションを渡します。

3. ヘルパーメソッドを記述する

ビューの中のページネーションを表示したい場所にwill_paginateヘルパーを記述します。

will_paginateを記述した位置にページネーションが表示されます。

Bootstrapのスタイルを適用する

will_paginateのページネーションにBootstrapのスタイルを適用したい場合、「will_paginate-bootstrap」を使用すると簡単に実装できます。

will_paginate-bootstrapの使用手順

Gemfileにgem 'will_paginate-bootstrap'を追加します。

will_paginateのrendererオプションにBootstrapPagination::Railsを渡します。

ページネーションにBootstrapのスタイルが適用されます。

参考URL

Railsプロジェクトでグラフ描画ライブラリChartkickを使用する手順

Railsプロジェクトでグラフ描画用のライブラリ「Chartkick」を使用する手順をまとめました。

Railsでグラフを描画する

Railsでグラフを描画する場合、「lazy_high_chart」「Chartkick」「Gruff」などのライブラリを利用することができます。

今回は、比較的簡単そうな「Chartkick」を使用してみました。

Chartkickの使用手順

  1. Gemfileを編集する
  2. JavaScriptのライブラリを読み込む
  3. グラフ描画用のデータを準備する
  4. ヘルパーメソッドでグラフを描画する

1. Gemfileを編集する

Gemfileにgem 'chartkick'を追加します。

2. JavaScriptのライブラリを読み込む

Chartkickを使用するためには、Chartkickのヘルパーメソッドを使用するより前にJavaScriptのライブラリを読み込む必要があります。ライブラリとして「Google Charts」を利用する場合、Google APIからファイルを読み込みます。

ここではlayouts/application.html.erbのheadタグにjavascript_include_tagを記述します。

「Google Charts」の代わりに「High Charts」を使用することもできるようです。

3. グラフ描画用のデータを準備する

グラフ描画用のデータは、配列かハッシュのいずれかの形式で準備します。

たとえば、コントローラの中で以下のような形でデータを作成します。

配列の1つめ(またはハッシュのkey)が横軸の値、配列の2つめ(またはハッシューのvalue)が縦軸の値になります。

一般的にはモデルからデータを作成するはずですから、おおよそ以下のような形式になることが多いと思われます。

4. ヘルパーメソッドでグラフを描画する

ビューの中のグラフを表示したい場所にヘルパーメソッドを記述します。

準備したデータを渡すだけでグラフを描画することができます。上記のline_chartの他にグラフの種類ごとにヘルパーメソッドが準備されています。

  • line_chart
  • pie_chart
  • column_chart
  • bar_chart
  • area_chart
  • geo_chart

詳細は公式ページを参照してください。

ヘルパーメソッドのオプション

ヘルパーメソッドにオプションを指定することで、見た目をカスタマイズすることができます。

グラフの高さを指定する

グラフの最小値、最大値を指定する

グラフの色を指定する

複数のグラフを重ねて表示する方法

複数のグラフを重ねて表示する場合は、ひとつひとつのグラフを表すハッシュを配列にしてヘルパーメソッドに渡します。グラフを表すハッシュは、namedataで構成します。nameにはグラフを表す名前、dataにはグラフ描画用のデータを指定します。nameに指定した名前は、グラフの凡例に反映されます。

以上です。

参考URL

Rails4でjQuery UIのdatepickerを利用する手順

Ruby on Rails 4のプロジェクトでjQuery UIのdatepickerを利用する手順をまとめました。

手順

手順の全体は以下のとおりです。

  1. Gemfileを編集する
  2. application.jsを編集する
  3. application.cssを編集する
  4. ビューを編集する
  5. JavaScriptを編集する

1. Gemfileを編集する

jquery-ui-rails」を使用します。Gemfileにjquery-ui-railsを追加します。

Gemfileを編集したのち、bundle installを実行します。

2. application.jsを編集する

app/assets/javascripts/application.jsを編集します。require jquery.ui.corerequire jquery.ui.datepickerを追加します。

3. application.cssを編集する

app/assets/stylesheets/application.cssを編集します。require jquery.ui.datepickerを追加します。

4. ビューを編集する

datepickerを適用する入力項目を参照可能にするためにビューを編集します。以下はsimple_formを利用したフォームにdatepickerクラスを設定する例です。

5. JavaScriptを編集する

assets/javascripts配下のJavaScriptファイルでdatepickerを実装します。以下はCoffeeScriptで設定する例です。

以上で設定は完了ですが、Rails4の場合はTurbolinksの関連で正常に動作しないようです。具体的には、初回読み込み時にはdatepickerが有効にならず、画面を再読み込みしたときに初めてdatepickerが有効になる、という状態になります。

Turbolinks対応

datepickerを正常に使用するためには、なんらかの形でTurbolinksに対応する必要があります。今回は、あまり望ましい対応ではないと思いますが、datepickerを利用するページでTurbolinksを無効にするという対応をとることにします。(他の方法を調べてみたけど正直よくわからなかった。。。)

特定のページでTurbolinksを無効にするには、link_tono_turbolink: trueを設定します。

リンク先のページを表示する際にアセットの再読み込みが発生し、datepickerが有効になります。

以上でdatepickerが利用可能になります。Turbolinks対応は、きっともっと良い方法があるはずと思われます。

rails_layoutでRailsプロジェクトのレイアウトにBootstrap3を適用する手順

rails_layoutを使用してRailsプロジェクトのレイアウトにBootstrap3を適用する手順をまとめました。

手順

  1. gemのインストール
  2. セットアップコマンドの実行
  3. 適用結果の確認

1. gemのインストール

Gemfileに必要なgemを記述します。

bundle installを実行します。

2. セットアップコマンドの実行

rails generateコマンドで、基本レイアウトをセットアップします。

実行時にファイルの上書き確認が発生する場合があります。問題なければYesで先に進めます。

3. 適用結果の確認

セットアップコマンドの適用結果を確認します。

作成・更新されるファイル

  • app/assets/stylesheets/application.css.scss
  • app/assets/stylesheets/framework_and_overrides.css.scss
  • app/assets/javascripts/application.js
  • app/views/layouts/application.html.erb
  • app/view/layouts/_messages.html.erb
  • app/view/layouts/_navigation.html.erb
  • app/view/layouts/_navigation_links.html.erb

application.css.scss

cssをscssに変更しているだけで、実質的な内容に変化はありません。

framework_and_overrides.css.scss

Bootstrap関連のCSSをインポートしています。また、その他の各種調整がなされています。

気に入らない部分があれば修正します。その場合、framework_and_overrides.css.scssを直接変更しても良いと思います。ただ、個人的には別途custom.css.scssというファイルを作ってそちらを編集するようにしています。

app/assets/javascripts/application.js

Bootstrap関連のJavaScriptのrequireが追加されます。

app/views/layousの各種ファイル

  • app/views/layouts/application.html.erb
  • app/view/layouts/_messages.html.erb
  • app/view/layouts/_navigation.html.erb
  • app/view/layouts/_navigation_links.html.erb

application.html.erbがBootstrapを適用した形式に更新されます。ナビゲーションバー用に_navigation.html.erbと_navigation_links.html.erbが作成されます。また、フラッシュメッセージ用に_messages.html.erbが作成されます。

以上です。