Rails 2.3.5のウェブアプリをWindowsのexeファイルにする

ローカルアプリケーションを作るときでも、ウェブインターフェースを付けたいことがあります。しかも、データベースも使いたい。そういう場合にはRailsを使えば開発が簡単になります。

しかし、作ったローカルアプリケーションを配布しようとすると問題が起きます。Railsアプリケーションは配布するようには作られていないからです。特に、Windowsで動作させるとなるとハードルは一気に高くなります。

ここではRails 2.3.5で作成したウェブアプリケーションWindows用のexeファイルにする方法を紹介します。

Ovewview

Rubyプログラムをexeにするツールはいくつかありますが、ここではRubyScript2Exeを使います。このエントリではRubyScript2Exeの動作環境の構築から実行までの手順、躓きやすい点について説明します。

より新しいツールとしてOCRAがありますが、Railsアプリケーションの場合は正常に動作しませんでした。

動作環境の構築

msysGit

RubyScript2Exeはgithubで公開されているバージョンを使いますので、msysGit (Git on Windows)をインストールしておきます。msysGitのサイトからダウンロード、インストールしてください。

Ruby

Windows用のRubyも幾つかありますが、今回動作確認したのはRubyInstallerの1.8.6-26です(RubyInstallerのファイルリストの一番下)。最新版の1.9.1-p378では、Rubyのプロセスがクラッシュすることがありました。

RubyInstallerはその名の通りインストーラになっていますので、そのままダウンロードしてインストールしてください。

Rubygemsの更新

Rails 2.3.5はRubygems 1.3.2以降に依存していますが、RubyInstallerでインストールされるRubygemsはバージョン0.9.4なので更新する必要があります。コマンドプロンプトを起動して以下のコマンドを実行します。(0.9.4から1.3.5への更新にgem update --systemは使用できません。)

> gem install rubygems-update
> update_rubygems
Railsのインストール

この辺はMacLinuxと変わりません。

> gem install rails -v 2.3.5

ついでにSQLite3アダプタもインストールしておきます。

> gem install sqlite3-ruby

アプリケーションの作成/展開

ここまででRailsアプリケーションを動作させる環境ができましたので、新しいアプリケーションを作成するなり、MacLinuxから持ってくるなりします。

ここでは例として「hi!」と表示するアプリケーション(?)、fooを作ります。

> rails foo
> ruby script\generate controller foos

app\controllers\foos_controller.rbの内容は下の通りです。

class FoosController < ApplicationController
  def hi
    render :text => 'hi!'
  end
end

これでアプリケーションを起動し、

> ruby script\server

http://127.0.0.1:3000/foos/hiを開けば「hi!」と表示されます。

exe化

RubyScript2ExeはRubyスクリプトをexe化するツールなので、Railsアプリケーションのように複数のファイルが含まれるものには、そのままでは適用できません。そこで、同じ作者によるTar2RubyScriptという、フォルダを自己解凍Rubyスクリプト(以下アーカイブ)に変換するツールを使います。

Tar2RubyScript

オリジナルのTar2RubyScriptRubygems 1.3.1までにしか対応していないため、Ryan Bookerによって修正されたバージョンを使います。まずgitを使ってインストールします。

> git clone git://github.com/ryanbooker/tar2rubyscript.git

Windows用のtarが同梱されているので、パスの通ったフォルダへコピーします。

> copy tar2rubyscript\tar.exe C:\WINDOWS

そしてTar2RubyScript自身をアーカイブにします。

> ruby tar2rubyscript\init.rb tar2rubyscript

これでtar2rubyscript.rbというスクリプトができます。このスクリプトを使うことで他のフォルダをアーカイブできます。

ただし、フォルダをアーカイブ化する際には、そのフォルダの中で最初に実行する.rbファイルが明確になっていなければなりません。Tar2RubyScriptは、フォルダの直下にあるinit.rbを最初に実行するようになっています。つまり、Railsアプリケーションをアーカイブ化するには、いわゆるRAILS_ROOTにscript/serverを実行するinit.rbを入れておかなければなりません。

例えば、以下のようなinit.rbを入れておけばRailsアプリケーションをアーカイブ化できます(at_exitについては後述します)。

at_exit do
  require "irb"
  require "drb/acl"
  require "sqlite3"
end

load "script/server"

準備ができましたので先程のfooアプリをアーカイブ化します。

> ruby tar2rubyscript.rb foo

foo.rbができるはずです。これを実行するとシステムの一時フォルダに展開されてWebrickが起動する様子が見られます。

> ruby foo.rb

もちろんhttp://127.0.0.1:3000/foos/hiにもアクセスできます。また、-eオプションなどを渡すこともできます。

> ruby foo.rb -e production
RubyScript2Exe

オリジナルのRubyScript2ExeRubygems 1.3.1にしか対応していないので、修正されたバージョンをインストールします。

> git clone git://github.com/ryanbooker/rubyscript2exe.git

そしてアーカイブ化しておきます。

> ruby tar2rubyscript.rb rubyscript2exe

rubyscript2exe.rbができるので、foo.rbを食わせます。この時、下のようにRUBYOPTを設定します。

> set RUBYOPT=
> ruby rubyscript2exe.rb foo.rb

するとfooアプリケーションが起動します。実はRubyScript2Exeはターゲットのスクリプトを実際に実行し、ロードしたファイルを記録しておいてexeに同梱することで(出来上がるexeは自己解凍ファイルです)gemなどの外部のファイルを利用可能にします。よってここでは一度http://127.0.0.1:3000/foos/hiにアクセスするなどして、アプリケーションの実際の動作をさせておくとファイルの取りこぼしがなくなります。

あるいは、起動しただけでは読み込まれないファイルがわかっている場合には、上のinit.rbに書いたようにat_exitの中でrequireするなどの方法で読み込ませることができます。

Ctrl-Cでfooを停止するとfoo.exeが作成されます。このfoo.exeにはRuby本体からfooアプリケーション、必要なgemまで全てが含まれていますので、そのまま他のマシンへコピーして実行できます。