読者です 読者をやめる 読者になる 読者になる

Vagrant が synced folder をマウントした後に rails server を自動起動したい。

独立環境を起動しながらもホストでファイルの編集をしたらそれがすぐにゲストに反映されるように、ということが Vagrant の Synced Folders を使えばできる。

例えば Rails プロジェクトのルートディレクトリに Vagrantfile を置き、そこから vagrant up する。何も設定しなければ、このホスト側の Rails のルートディレクトリがゲスト側の /vagrant ディレクトリになり、ホスト側でファイルを編集すると、すぐゲスト側に反映される。嬉しい。

さて、この /vagrant ディレクトリで rails server したい。一回すること自体は、 provisioning のタイミングは既にマウントされているので、好きなようにやったらいいんだけど、 vagrant halt && vagrant up の場合再度 provisioning されないので、できれば初回(と思われるタイミング)で自動起動の設定をしたい。

Ubuntu でサービスの自動起動となれば、 Upstart である。

vagrant-mounted イベント

さて、問題はいつその Upstart job を start したら良いのかって話ですが、なんと vagrantスクリプトよく出来ていて vagrant-mounted という Upstart のイベントを emit してくれる!

Ubuntu 用の Guests Plugin がやっている。

ちなみにこれ、どこから呼び出されているかというと、

  1. vagrant up コマンド
  2. virtualbox provider の action_up > action_start > action_boot
  3. ビルトインの SyncedFolders Action
  4. VirtualBox 用 Provider Plugin の SyncedFolder

と来て、最後に Ubuntu の Guests Plugin になるみたい。 Vagrant の設計結構気持ちいいですね。

Upstart Job Configuration

というわけで、上記のイベントで start する System Job の conf を書きます。落とすのは network-services が落ちた時で良さそう。

description "rails server"
author "oogatta <oogatta@gmail.com>"

start on vagrant-mounted
stop on stopping network-services

setuid vagrant
setgid vagrant

chdir /vagrant

script
	export HOME=/home/vagrant
	export PATH=/home/vagrant/.rbenv/shims:/home/vagrant/.rbenv/bin:$PATH
	exec rails server
end script

daemonize は Upstart がやってくれる。 script の中で exec しない場合は expect する必要がある…と、思う、多分…。

vagrant ユーザで rbenv を作ってる環境だからユーザを変えてるので面倒だけど、そうじゃなかったら一瞬です。

Vagrantfile

最後にこれを Vagrantfile から provisioning でぶちこむ。

(略)
$start_rails_script = <<SCRIPT
echo "set & start rails server"
if [[ ! -f /etc/init/oogatta-rails.conf ]]; then
  cp /vagrant/.vagrantbox/oogatta-rails.conf /etc/init/oogatta-rails.conf
  chmod +x /etc/init/oogatta-rails.conf
  start oogatta-rails
fi
SCRIPT

便利な世の中だなあ。