#292 Virtual Machines with Vagrant
- Download:
- source codeProject Files in Zip (41.1 KB)
- mp4Full Size H.264 Video (27.3 MB)
- m4vSmaller H.264 Video (13.6 MB)
- webmFull Size VP8 Video (13.2 MB)
- ogvFull Size Theora Video (30.4 MB)
Railsデベロッパーとして、自分の開発環境が本番稼働環境とかなり違っていることに気づくときがあるでしょう。実際、本番稼働時とは違うOSでアプリケーションを開発するということもめずらしいことではありません。またRailsアプリケーションでは、別のマシンに再現するのが不可能なほど複雑な依存関係を持っているという場合もあります。
Vagrantはこのような場合に役に立ちます。仮想環境を設定・管理して自分のOSの中に小さなlinuxディストリビューションを構築できます。自分のアプリケーションとその依存関係を仮想マシンで実行でき、またそれを他の人と共有できるよう持ち運べる形式のパッケージに保存することができます。
すべてのRailsデベロッパーにVagrantを試してみることをお勧めします。少なくともそれによって、Railsアプリケーションのための本番稼働環境の構築方法をよりよく理解できるようになるでしょう。またステージング環境を構築したり、アプリケーションの開発時に使用することもできます。
VirtualBoxとVagrantをインストールする
VagrantはOracleのVirtualBoxを利用します。もしマシンにインストールされていなければ、まずそこから始めます。VirtualBoxはWindows/OS X/Linuxで利用可能なので、いずれのOSを使用していても環境にあったバージョンを見つけることができます。VirtualBoxがインストールされればVagrantをインストール可能になります。VagrantはRuby gemで、このコマンドを実行してインストールを行います。
$ gem install vagrant
Boxを追加する
次のステップでは仮想マシンを追加します。それをVagrantではboxと呼びます。Vagrantbox.esでは多くの種類のboxが公開されていて、ダウンロードが可能です。ここではubuntu lucid 32を使うことにします。これはVagrantサイトで提供されていてUbuntu Linux 10.04をベースにしています。boxをインストールするには、boxの名前とURLを指定してvagrant box add
を実行します。
$ vagrant box add lucid32 http://files.vagrantup.com/lucid32.box [vagrant] Downloading with Vagrant::Downloaders::HTTP... [vagrant] Downloading box: http://files.vagrantup.com/lucid32.box [vagrant] Extracting box... [vagrant] Verifying box... [vagrant] Cleaning up downloaded box...
boxはかなり大きい(約数100MB)場合があり、ダウンロードに時間がかかります。もしすでにダウンロード済であれば代わりにファイルURLを渡してローカルのboxファイルからインストールできます。
boxがダウンロードされてインストールされたら、それを用いて仮想環境を構築できます。Vagrantでは通常これをプロジェクトごとに設定します。まだ設定していないのでここで新規に作成し、そのディレクトリに移動します。
$ rails new todo $ cd todo
このアプリケーションとその依存関係専用に仮想マシンを作成するために、vagrant init
を実行し、使用したいboxの名前を渡します。
$ vagrant init lucid32 create Vagrantfile
このコマンドはVagrantfile
というファイルを作成するだけです。このファイルには、このアプリケーションのVagrant boxの設定情報が含まれています。デフォルトでは、どのboxを使用するかを指定する行を除いて、情報はすべてコメントアウトされています。
Vagrant::Config.run do |config| # All Vagrant configuration is done here. The most common configuration # options are documented and commented below. For a complete reference, # please see the online documentation at vagrantup.com. # Every Vagrant virtual environment requires a box to build off of. config.vm.box = "lucid32" # Rest of file omitted. end
その他にここで設定する多くのオプションがあるので、ここで少し時間をとってすべてに目を通しておくことをお勧めします。
Vagrant仮想マシンを起動する
さあそれではマジックの時間です。vagrant up
を実行すると、仮想マシンが構築されます。これは数分かかりますが、起動が完了するとSSHでアクセスすることができます。
$ vagrant ssh
これでUbuntu仮想マシンの中に入りました。これはほとんど何もインストールされていない必要最小限の設定ですが、何点か注記すべき点があります。ひとつは、vagrant
という名前のユーザが作成されて、我々は今そのユーザでログインしています。もうひとつは、我々はsudo
権限を持っておりパスワードを入力する必要がなく、これはローカルの開発マシンにとっては好都合です。Vagrantはまた/vagrant
にshared direcotryを設定しますが、それはRailsアプリケーションがあるディレクトリをpointしています。
アプリケーションの依存関係をインストールする
ここでの目的は仮想マシン上にRailsアプリケーションを稼働させることなので、依存関係を設定する必要があります。まずRubyとSqliteがインストールされていることを確認します。仮想マシンには、すでにRuby 1.8.7がインストールされていますが、これはChefレシピを実行するためです。
Chefはサーバ環境設定を自動化する方法を提供します。Ruby 1.9とSqliteをインストールするために必要なChefレシピを適用すると自動でインストールが行われます。ChefとVagrantを連携させることもできますが、それ自体で一つの大きな話題なので、将来のエピソードで独立して扱おうと思います。その代わりに今回はChefを使わずにサーバを構築することにします。それによって全体がどのように動作するかについてよりよく理解できるでしょう。
まずapt-get
を使ってインストールされたソフトウェアが最新であることを確認します。
$ sudo apt-get update
それが終わったら、必要なソフトウェア(build-essential, ZLib, Git, Sqlite3)をインストールします。
$ sudo apt-get install build-essential zlib1g-dev git-core sqlite3 libsqlite3-dev
後残っているインストールが必要なものはRuby 1.9です。これをゼロからインストールするか、あるいはRVMを使用できますが、今回はより新しいrbenvというツールを使います。Vagrantを使うことの意義は、このような今まで使ったことがないツールを安全な環境で実験的に試せるというところにあります。もしうまくいかなければ仮想マシンを削除して最初からやり直すことができます。
仮想マシンにrbenvをインストールするためには、rbenvのREADMEのセクション2.1にあるコマンドを実行するだけです。まず最初にリポジトリを~/.rbenv
にcloneします。
$ cd $ git clone git://github.com/sstephenson/rbenv.git .rbenv
次にrbenvのbin
ディレクトリをPATHに追加し、initコマンドを.bash_profileに追加します。
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile $ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
これらの変更を有効化させるために.bash_profileを再読み込みします。
$ source .bash_profile
これでrbenv
コマンドを使用してRubyのバージョンを管理できるようになりましたが、まだRubyをインストールする方法がありません。このためにRuby Buildを使用します。必要な作業としては、Gitリポジトリをcloneしてそのディレクトリに移動し、インストールスクリプトを実行します。
$ git clone https://github.com/sstephenson/ruby-build.git $ cd ruby-build $ sudo ./install.sh
これでrbenvを使ってRuby 1.9.2の最新バージョンをインストールできます。
$ rbenv install 1.9.2-p290
これを実行するとしばらく時間がかかりますが、それが終わるとRuby 1.9.2のコンパイルに成功しているはずです。このようにバイナリファイルを修正した場合はいつもrbenv rehash
を実行し、次のコマンドを実行して1.9.2 を仮想マシン上のRubyのデフォルトバージョンに設定します。
$ rbenv global 1.9.2-p290
Rubyのバージョンを確認してみると、期待どおり1.9.2となっています。
$ ruby -v ruby 1.9.2p290 (2011-07-09 revision 32553) [i686-linux]
Railsアプリケーションのインストール
Rubyの正しいバージョンがインストールできたので、次はRailsアプリケーションを動かす作業に移ります。アプリケーションのあるshared directoryに移動して依存関係をインストールするためにbundleを実行すると、一つ問題が発生します。
vagrant@lucid32:~$ cd /vagrant/ vagrant@lucid32:/vagrant$ bundle bundle: command not found
これを解決するためにはBundler gemをインストールします。
$ gem install bundler
このgemをインストールしたらrbenv rehash
を再度実行してbundle
の実行ファイルを設定します。これでbundle
を実行してアプリケーションのgemをインストールできるようになりました。
アプリケーションのサーバを起動しようとすると、JavaScriptランタイムが見つからないというエラーが返されます。Rails 3.1の実行にはJavaScriptが必要で、一方Ubuntuにはデフォルトでは入っていないため、このエラーは当然です。これを簡単に解決するためには、仮想マシン上でアプリケーションのGemfileにtherubyracerというgemを追加しbundleを実行します。これによってV8 JavaScriptエンジンがインストールされます。
gem 'therubyracer'
gemがインストールされたので再度サーバを起動してみます。
$ bundle exec rails s
今回は起動が成功し、アプリケーションが3000番ポートで稼働してます。しかし仮想マシン上で動作しているため、ブラウザで確認することはできません。Vagrantに対してポートを我々のマシンにforwardするよう指示する必要があり、そのためにプロジェクトのVagrantfile
を修正します。次の行を非コメント化し、名前をよりふさわしいものに修正して、仮想マシンの3000番ポートをローカルマシンの同じポート番号にforwardするように指示します。
config.vm.forward_port "rails", 3000, 3000
設定を変更したら、仮想マシン内でexit
を実行してVagrantシェルから抜け出し、vagrant reload
を実行して仮想マシンをリロードします。これによって仮想マシンがシャットダウンし、その後リロードされます。リロードされたら、再度SSHでその中に入れます。
$ vagrant ssh
仮想マシン上で、アプリケーションのディレクトリに移動し、再度サーバを起動します。
vagrant@lucid32:~$ cd /vagrant vagrant@lucid32:/vagrant$ bundle exec rails s
これによりサーバが再起動しますが、今回はローカルマシンからアクセスできます。
Rails applicationがVagrantと共有されるようになったので、おこなった修正はすべて仮想マシン内に反映されます。/public/index.html
のデフォルトページを修正してからリロードすると修正をすぐに確認することができます。
<h2>You’re riding Ruby on Rails on Vagrant!</h2>
その他のVagrantコマンド
Vagrantには仮想マシンの管理に役立ついくつかのコマンドがあります。仮想マシンの現在の状態を確認するためにはvagrant status
を実行します。
$ vagrant status Current VM states: default running The VM is running. To stop this VM, you can run `vagrant halt` to shut it down forcefully, or you can run `vagrant suspend` to simply suspend the virtual machine. In either case, to restart it again, simply run `vagrant up`.
マシンの一時停止とそこからの復帰にはsuspend
とresume
を使用します。
$ vagrant suspend [default] Saving VM state and suspending execution... $ vagrant resume [default] Resuming suspended VM... [default] Booting VM... [default] Waiting for VM to boot. This can take a few minutes. [default] VM booted and ready for use!
仮想マシンを完全にシャットダウンするにはvagrant halt
を使用します。マシンを再度起動するにはvagrant up
を使用します。
もっとも便利なコマンドのひとつはvagrant package
です。このコマンドは現在の状態の仮想マシンをpackage.box
という名前のファイルにパッケージ化します。そうすることによって、このファイルを配布して構築した仮想マシンを簡単に再現することができます。vagrant destroy
を使って仮想マシンを削除したら、最初に仮想マシンを構築するときに使用したのと同じvagrant box add
コマンドで復元できます。
Vagrantについての今回のエピソードは以上です。Railsアプリケーションの実行時の依存関係を取り込んで仮想環境に隔離した状態で構築してくれる優れたソリューションです。実行環境をパッケージ化して他の開発者に配布したり、本番稼働サーバをシミュレートしたり、ステージングサーバとしても使用できます。VagrantはChefと合わせて使うとさらに便利なツールになりますが、それについては将来のエピソードで取り上げることにします。