railsをオフラインでインストールする手順

もう5周遅れくらいだけど、Ruby on Railsなるものを使ってみようかな、と思った。
しかし対象のサーバは内部用のためプライベートネットワークで閉じており、インターネットには直接繋がらない。ということでパッケージだけ手で持ってきて手動で入れよう……と思ったら、これがあんまりにあんまりな茨(イバラ)の道だった。

ということで最初に言っておくと「railsをオフライン環境で構築しよう、とかバカなことを考えるのはやめとけ」ってことになるのだが、まぁ書いておく。railsは基本的な仕組みが「サーバはインターネットに直接通信できること」を前提に作られているので、オフライン環境を作ろうとすると本当にハマりまくる。
しかしRuby on Rails使ってる人たちは、直接インターネットに出られないバックエンドサーバとかを構築するときは、どうしているんだろう? 素朴な疑問だ。

環境

gemコマンドを多用するけど、Rubyは1.9系なら最初からgemコマンドが付いているから、別途入れる必要はない。

gemコマンドでローカルファイルからインストール

最初に、gemコマンドの使い方。

デフォルトではgemコマンドはオンラインインストールしようとするため、手で拾ってきた .gem ファイルをインストールするには、--localオプションを付ければ良い。この場合、ファイル名を指定しても良いし、パッケージ名だけ指定してもカレントディレクトリ内のgemファイルをよろしく探してくれる。

# gem install rails-3.2.8.rc1.gem --local
もしくは
# gem install rails --local

railsのインストールその1

ではインターネットへの接続を持っていないサーバなので、手でパッケージファイルを持ってきて入れることにしよう。ここで色々と(公式ドキュメント含めて)探してみたが、railsを入れるときはgemコマンドでオンラインから自動ダウンロードで入れろ……という記述ばかりで役に立たない。

仕方が無い、と配布元からダウンロードしようとしたが、

やはりgemコマンドで入れろとしか書かれておらず、モノへのリンクが無い。なんだこりゃ。

で、さんざん探し回ったところ、

モノは上記のGitHubにあるらしい。じゃぁ公式ページのdownloadから素直にリンク張っておけばいいのに……。ここでは3-2-stableのbranchを使うことにする。ZIPでダウンロードしてサーバに設置して展開。

さっそくrailsを入れようとしてみる
# gem install rails-3.2.8.rc1.gem --local
ERROR:  While executing gem ... (Gem::DependencyError)
    Unable to resolve dependencies: rails requires activesupport (= 3.2.8.rc1), actionpack (= 3.2.8.rc1), activerecord (= 3.2.8.rc1), activeresource (= 3.2.8.rc1), actionmailer (= 3.2.8.rc1), railties (= 3.2.8.rc1), bundler (~> 1.0)

ふむ。これらactivesupportとかずらずら足りないと言っているものは、railsGitHubの配布物に同梱されているので、一つ一つ手で入れてみるか。

railsに必要なパッケージを事前にインストールして準備する

まずrailsのパッケージを展開してできているサブディレクトリ[activesupport]に入ってインストールしてみる。

activesupport
# gem install activesupport --local
ERROR:  While executing gem ... (Gem::DependencyError)
    Unable to resolve dependencies: activesupport requires i18n (~> 0.6), multi_json (~> 1.0)

追加モジュール、i18nとmulti_jsonとやらが要るらしい……。gemファイルを手でダウンロードするには、rubygems.orgの/gems/フォルダの下から落とす。

から i18n-0.6.0.gem と multi_json-1.3.6.gem をダウンロードして入れてみる。

# gem install i18n-0.6.0.gem --local
Successfully installed i18n-0.6.0
1 gem installed
Installing ri documentation for i18n-0.6.0...
Installing RDoc documentation for i18n-0.6.0...

入った。同様に、multi_jsonもインストールした。

ということで、再びactivesupportを入れてみよう。

# cd activesupport
# gem install activesupport --local
Successfully installed activesupport-3.2.8.rc1
1 gem installed
Installing ri documentation for activesupport-3.2.8.rc1...
Installing RDoc documentation for activesupport-3.2.8.rc1...

入った。

actionpack

では続いて、railsのサブパッケージのactionpackも入れよう。

# cd actionpack
# gem install actionpack --local
ERROR:  While executing gem ... (Gem::DependencyError)
    Unable to resolve dependencies: actionpack requires activemodel (= 3.2.8.rc1), rack-cache (~> 1.2), builder (~> 3.0.0), rack (~> 1.4.0), rack-test (~> 0.6.1), journey (~> 1.0.4), sprockets (~> 2.1.3), erubis (~> 2.7.0)

む……メンドくさそうだなぁ……。

インストールされたgem確認

上記のモジュールをインストールできたか、確認する。

# gem list

*** LOCAL GEMS ***

activemodel (3.2.8.rc1)
activesupport (3.2.8.rc1)
bigdecimal (1.1.0)
builder (3.0.0)
bundler (1.1.5)
erubis (2.7.0)
hike (1.2.1)
i18n (0.6.0)
io-console (0.3)
journey (1.0.4)
json (1.5.4)
mail (2.4.4)
mime-types (1.19)
minitest (2.5.1)
multi_json (1.3.6)
polyglot (0.3.3)
rack (1.4.1)
rack-cache (1.2)
rack-test (0.6.1)
rake (0.9.2.2)
rdoc (3.9.4)
sprockets (2.4.5)
tilt (1.3.3)
treetop (1.4.10)
sprocketsでハマる

さて準備できたので、railsのサブパッケージをもりもり入れよう。

# gem install actionpack --local
ERROR:  While executing gem ... (Gem::DependencyError)
    Unable to resolve dependencies: actionpack requires sprockets (~> 2.1.3)

あれ、怒られる……なぜだ? sprockets (2.4.5)が入っているのに……。と思っていたら、(~> 2.1.3)というのは、2.1.3以上、2.2未満という意味らしい。つまり2.1.xじゃないとダメだと……。なにそれ。Σ(゜д゜;)

ということで仕方がないので、sprockets 2.4.5を消して2.1.3を入れることにする。

から2.1.3をダウンロードして、今入ってるのをいったん消して入れ直す。

# gem uninstall sprockets
Remove executables:
        sprockets

in addition to the gem? [Yn]  y
Removing sprockets
Successfully uninstalled sprockets-2.4.5
# gem install sprockets
Successfully installed sprockets-2.1.3
1 gem installed
Installing ri documentation for sprockets-2.1.3...
Installing RDoc documentation for sprockets-2.1.3...
#

railsのインストールその2

ということで必要なモジュール類のお膳立てが整ったので、actionpackなどサブモジュールを一つ一つ手で入れ、最後に、

# gem install rails --local

でインストールできた。長かった……。(´∀`)

railsコマンドでアプリひな形作成後の作業

ではさっそく、rails newでアプリのひな形を作成しよう。booksという名前で作ってみる。

$ rails new books
      create
      create  README.rdoc
      create  Rakefile
      create  config.ru
      create  .gitignore
      create  Gemfile
      create  app
      create  app/assets/images/rails.png
      create  app/assets/javascripts/application.js
      create  app/assets/stylesheets/application.css
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/mailers
      create  app/models
      create  app/views/layouts/application.html.erb
      create  app/mailers/.gitkeep
      create  app/models/.gitkeep
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/secret_token.rb
      create  config/initializers/session_store.rb
      create  config/initializers/wrap_parameters.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  doc
      create  doc/README_FOR_APP
      create  lib
      create  lib/tasks
      create  lib/tasks/.gitkeep
      create  lib/assets
      create  lib/assets/.gitkeep
      create  log
      create  log/.gitkeep
      create  public
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/favicon.ico
      create  public/index.html
      create  public/robots.txt
      create  script
      create  script/rails
      create  test/fixtures
      create  test/fixtures/.gitkeep
      create  test/functional
      create  test/functional/.gitkeep
      create  test/integration
      create  test/integration/.gitkeep
      create  test/unit
      create  test/unit/.gitkeep
      create  test/performance/browsing_test.rb
      create  test/test_helper.rb
      create  tmp/cache
      create  tmp/cache/assets
      create  vendor/assets/javascripts
      create  vendor/assets/javascripts/.gitkeep
      create  vendor/assets/stylesheets
      create  vendor/assets/stylesheets/.gitkeep
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
         run  bundle install
Fetching gem metadata from https://rubygems.org/.
Error Bundler::HTTPError during request to dependency API
Fetching full source index from https://rubygems.org/
Could not reach https://rubygems.org/
$

む、最後のBundlerでインターネットに接続しようとして失敗した。相変わらずめんどくさいヤツだな……。(´・ω・)

Bundler相当のことを手動で行う

ということで、Bundlerが自動でやる(はず)のことを手動でやろう。アプリのディレクトリに入り、rails serverコマンドで起動しようとすればエラーを吐くのでそれを参照する。

$ cd books
$ rails server
Could not find gem 'jquery-rails (>= 0) ruby' in the gems available on this machine.
Run `bundle install` to install missing gems.

ふむ。"jquery-rails"が要るようだな。と、足りないモノが分かるのでこれを地道に入れていく。結局、追加で手で入れたモノは以下のものだった。

先ほどと同じように、gemファイルを拾って--localオプションでインストールする。

Gemfileの修正

これで必要なものは全部入れたはずなのだが、まだエラーが出る。そろそろ疲れてきたぞ……。(´・ω・)

$ rails server
/usr/local/lib/ruby/gems/1.9.1/gems/execjs-1.4.0/lib/execjs/runtimes.rb:51:in `autodetect': Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)
        from /usr/local/lib/ruby/gems/1.9.1/gems/execjs-1.4.0/lib/execjs.rb:5:in `<module:ExecJS>'
        from /usr/local/lib/ruby/gems/1.9.1/gems/execjs-1.4.0/lib/execjs.rb:4:in `<top (required)>'
        from /usr/local/lib/ruby/gems/1.9.1/gems/coffee-script-2.2.0/lib/coffee_script.rb:1:in `require'
        from /usr/local/lib/ruby/gems/1.9.1/gems/coffee-script-2.2.0/lib/coffee_script.rb:1:in `<top (required)>'
        from /usr/local/lib/ruby/gems/1.9.1/gems/coffee-script-2.2.0/lib/coffee-script.rb:1:in `require'
        from /usr/local/lib/ruby/gems/1.9.1/gems/coffee-script-2.2.0/lib/coffee-script.rb:1:in `<top (required)>'
        from /usr/local/lib/ruby/gems/1.9.1/gems/coffee-rails-3.2.2/lib/coffee-rails.rb:1:in `require'
        from /usr/local/lib/ruby/gems/1.9.1/gems/coffee-rails-3.2.2/lib/coffee-rails.rb:1:in `<top (required)>'
        from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-1.1.5/lib/bundler/runtime.rb:68:in `require'
        from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-1.1.5/lib/bundler/runtime.rb:68:in `block (2 levels) in require'
        from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-1.1.5/lib/bundler/runtime.rb:66:in `each'
        from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-1.1.5/lib/bundler/runtime.rb:66:in `block in require'
        from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-1.1.5/lib/bundler/runtime.rb:55:in `each'
        from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-1.1.5/lib/bundler/runtime.rb:55:in `require'
        from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-1.1.5/lib/bundler.rb:119:in `require'
        from /home/bin/osumi/books/config/application.rb:7:in `<top (required)>'
        from /usr/local/lib/ruby/gems/1.9.1/gems/railties-3.2.8.rc1/lib/rails/commands.rb:53:in `require'
        from /usr/local/lib/ruby/gems/1.9.1/gems/railties-3.2.8.rc1/lib/rails/commands.rb:53:in `block in <top (required)>'
        from /usr/local/lib/ruby/gems/1.9.1/gems/railties-3.2.8.rc1/lib/rails/commands.rb:50:in `tap'
        from /usr/local/lib/ruby/gems/1.9.1/gems/railties-3.2.8.rc1/lib/rails/commands.rb:50:in `<top (required)>'
        from script/rails:6:in `require'
        from script/rails:6:in `<main>'

さんざん調べたところ、これはRuby on Railsではそういうものだそうで、アプリのディレクトリにあるGemfileという設定ファイルに以下の2行を追加すればいいらしい。

gem 'execjs'
gem 'therubyracer'

……な、なんだそりゃ? 普通にバグだろ。(´・ω・)(´・ω・) と、Ruby on Railsに不信感を持つ私は思った。こんなバギーなもの、みんなよくもまぁ使おうと思うね……。

therubyracer

ということで、therubyracer-0.10.2.gemも必要になった。

からダウンロードし、同じようにインストールする。

# gem install therubyracer --local
ERROR:  While executing gem ... (Gem::DependencyError)
    Unable to resolve dependencies: therubyracer requires libv8 (~> 3.3.10)

うーむ、これを入れようとすると libv8も入れないといけない。先ほどsprocketsでハマったように、libv8の3.3系列でないとダメなので、最新版の3.11.8.3ではなく、3.3.10.4を入れることにする。

下部の「Show all versions (38 total)」から、" 3.3.10.4 November 15, 2011 x86_64-linux " libv8-3.3.10.4-x86_64-linux.gem を選ぶ。他にdarwin用、FreeBSD用などプラットフォームごとにあるので注意。

ということでお膳立てができたので、libv8とtherubyracerを入れる。

# gem install libv8 --local
Successfully installed libv8-3.3.10.4-x86_64-linux
1 gem installed
Installing ri documentation for libv8-3.3.10.4-x86_64-linux...
Installing RDoc documentation for libv8-3.3.10.4-x86_64-linux...
# gem install therubyracer --local
Building native extensions.  This could take a while...
Successfully installed therubyracer-0.10.2
1 gem installed
Installing ri documentation for therubyracer-0.10.2...
Installing RDoc documentation for therubyracer-0.10.2...
#

はー、やっと入ったわ。(*´∀`)

railsアプリの起動

$ rails new books
$ cd books
$ vi Gemfile
(ファイルを修正して 'execjs''therubyracer' を追加)
$ rails server

これで、 http://(IPアドレス):3000/ でアクセスできる。疲れ果てたわ。_(:3」∠)_パタ…

感想

インターネットに直接接続できるサーバじゃないとRuby on Railsは使い物にならない。組織内向けの内部アプリ等で、セキュリティ要件的にインターネットに通信できないサーバで構築するのは、地雷を踏みに行くようなものでやめておくべき。

また、前段にWebサーバ・後段にアプリサーバという定番の構成を作って、アプリサーバはインターネット側へ通信させないようなセキュリティ設定を施したサーバ構成を作っても、運用上不便すぎるので、1週間も経てばアプリサーバもインターネットに直接通信させるようにしてしまうだろう。良くないね。

こういうことをハッキリ書いている人がいないようなので敢えてdisっておくが、Ruby on Railsって、あんまり良くないよ。正直、私は趣味でも業務でもRuby on Railsは使いたくないなぁ。という結論になった。