Syntax Error.

[Sy] Railsの環境構築でグローバルのgemを汚さずにプロジェクト内にbundle install する手順

2016/07/21

Rails の環境を作る際、普通に rails(gem) をインストールして、rails newでプロジェクトを作るとグローバルな gem 環境が汚れます。それを避けてプロジェクト内に gem をインストールする手順です。

前提

  • Ruby インストール済み(今回は 2.3.1を使います)
  • グローバルな gem に bundler インストール済み
  • OS は Linux または Mac OS X

手順まとめ

以下の手順でプロジェクトsampleを構築していきます。

  1. とりあえず一旦 rails をインストールする。(=仮railsと呼ぶ)
  2. 仮rails を使ってrails newでプロジェクトsampleを作成する。
  3. 用の済んだ仮rails 関連のファイルをすべて削除する。
  4. 作成済みのsampleプロジェクトのディレクトリへ移動し、配下のディレクトリを指定してbundle installを実行する。
  5. 環境完成。rails sで起動できる。

では、この手順で説明していきます。

1. とりあえず一旦 rails をインストールする。(=仮railsと呼ぶ)

今回やることは、 プロジェクト内の vender/bundle というディレクトリ内に rails の環境を閉じ込める ということになります。

なので、何はともあれその枠となるプロジェクトを作らないといけないのですが、そこで一旦 rails が必要になるんですね。

ということで、その仮となる rails をインストールするための Gemfile を作るのが最初にやることです。次のコマンドを入力してください。

$ cat << EOS > Gemfile
heredoc% source "http://rubygems.org"
heredoc% gem "rails"
heredoc% EOS

このコマンドの意味は、 EOS(End of String の略。これは慣習的に使われるだけで、別になんでもOKです。)に囲まれた2行目〜3行目の文字列を Gemfile として書き出す ということになります。

heredoc%という部分は、勝手に出てくるプロンプトですので入力しないでOKです。

ちなみにこういった文字列の書き方は ヒアドキュメント と言われます。(なのでheredoc%というプロンプトが出てくるわけです)

手順の説明に戻ります。先ほどのコマンドで、ヒアドキュメントの内容が Gemfile に書きだされて、ファイルが作成されているはずです。

$ ls
Gemfile

$ cat Gemfile
source "http://rubygems.org"
gem "rails"

中身を cat で確認すると、このような2行が書き出されてます。

では、この Gemfile を使って rails をインストールします。普通に bundle install としてしまうと gem がグローバルにインストールされてしまうので、.bundleというディレクトリを作ってそこへ gem をインストールさせます。

$ bundle install --path .bundle/
Fetching gem metadata from http://rubygems.org/
・
・
・
Installing rake 11.2.2
・
・
・
Using bundler 1.12.5
・
・
・
Installing rails 5.0.0
Bundle complete! 1 Gemfile dependency, 39 gems now installed.
Bundled gems are installed into ./.bundle.

rails のインストールなので数分かかります。インストールが終わったら、ls コマンドで確認してみます。

$ ls
.bundle      Gemfile      Gemfile.lock

.bundle ディレクトリが作られているのがわかります。この中に、先ほどインストールした gem たちが入ってるので、それも確認してみましょう。

$ ls .bundle/ruby/2.3.0/gems/
arel-7.1.0                  mime-types-data-3.2016.0521 rails-html-sanitizer-1.0.3
..                          builder-3.2.2               mini_portile2-2.1.0         railties-5.0.0
actioncable-5.0.0           concurrent-ruby-1.0.2       minitest-5.9.0              rake-11.2.2
actionmailer-5.0.0          erubis-2.7.0                nio4r-1.2.1                 sprockets-3.7.0
actionpack-5.0.0            globalid-0.3.6              nokogiri-1.6.8              sprockets-rails-3.1.1
actionview-5.0.0            i18n-0.7.0                  pkg-config-1.1.7            thor-0.19.1
activejob-5.0.0             loofah-2.0.3                rack-2.0.1                  thread_safe-0.3.5
activemodel-5.0.0           mail-2.6.4                  rack-test-0.6.3             tzinfo-1.2.2
activerecord-5.0.0          method_source-0.8.2         rails-5.0.0                 websocket-driver-0.6.4
activesupport-5.0.0         mime-types-3.1              rails-dom-testing-2.0.1     websocket-extensions-0.1.2
Ruby のバージョンと gem のインストール先

今回使っている Ruby のバージョンは 2.3.1 でした。でも gem のインストール先は「.bundle/ruby/2.3.0/gems/」になってます。これは、bundler が Ruby のマイナーバージョン(今回だと2.3)ごとにディレクトリを作って、そこにインストールするということをやっているためです。

また、bundler は最初にbundle installで指定されたディレクトリを覚えていて、ここに書かれています。

$ cat .bundle/config
---
BUNDLE_PATH: ".bundle/"
BUNDLE_DISABLE_SHARED_GEMS: true

BUNDLE_PATHはわかりやすいですね。先ほど--pathオプションで指定したディレクトリになります。今回はやらないですが、以降bundle installをここで実行したら、--pathオプションを指定しなくても.bundle/へインストールされます。

もう一つ。BUNDLE_DISABLE_SHARED_GEMStrueになってますが、これは「共有されている gem を無効にする」みたいな意味になります。要するに、グローバルの gem を使わずに、BUNDLE_PATHで指定されたディレクトリにインストールされた gem しか使いませんよ、ということですね。

ちょっと bundler の説明になってしまいましたが、続きをやっていきます。

2. 仮rails を使って rails new でプロジェクト sample を作成する。

先ほど仮の rails をインストールしたので、rails newコマンドでプロジェクトを作ります。

が、ここで2つほど注意点があります! 次の2点です。

  • rails newの前にbundle execをつける。
  • rails new--skip-bundleオプションをつける。

ということで、実行するコマンドは以下のようになります。

$ bundle exec rails new sample --skip-bundle
      create
      create  README.md
      ・
      ・
      ・
      remove  config/initializers/cors.rb

これでsampleというプロジェクトが作られました。

$ ls
.bundle      Gemfile      Gemfile.lock sample

では先ほどの2つの注意点について補足していきます。

rails newの前にbundle execをつける。

これはすごくわかりづらいと思います。

Rails について調べてると、bunle execをつける場合とつけない場合の両方の情報が見つかります。なぜかというと、 環境によってどちらを使うべきか変わってくるから です。

今回のように、パスを指定して gem をインストールした場合、 bundle execをつけることで指定したパスの配下にある gem を使って実行します。

どういうことかというと、先ほどの.bundleディレクトリの下に、次のようなディレクトリがあります。

$ ls .bundle/ruby/2.3.0/bin/
erubis    nokogiri  rackup    rails     rake      sprockets thor

ここにあるrailsというバイナリ(実行できるファイル、という意味でとらえてもらえれば大丈夫です!)を使って実行するために、bundle exec rails new ...としていたということです。

それに対し、bundle execなしの場合はグローバルの gem を使おうとします。

試しにbundle execありなし両方で、rails -vで rails のバージョンを確認してみると、こうなります。

まずありの場合。

$ bundle exec rails -v
Rails 5.0.0

バージョンが表示されました。続いて、なしの場合。

$ rails -v
Rails is not currently installed on this system. To get the latest version, simply type:

    $ sudo gem install rails

You can then rerun your "rails" command.

何やらメッセージが表示されます。これは、

「Railsはこのシステムにはインストールされてないよ。最新バージョンをインストールしたいなら、sudo gem install railsってコマンド実行してね。そうしたらrailsコマンド使えるようになるよ。」

という意味になります。今回の環境ではグローバルに rails をインストールしていないので、こう言われちゃうわけです。

rails new--skip-bundleオプションをつける。

2つ目は単純です。

通常、何もオプションをつけずにrails newを実行すると、bundle installが自動的に走ります。そのため、グローバルな gem 環境が汚れてしまうので、--skip-bundleオプションをつけることでbundle installが走るのを止めているということです。

・・・と、ちょっと長くなりましたが、なぜbundle exec rails new sample --skip-bundleというコマンドにする必要があるのかの補足でした。

ここまで整理すると、

  • 仮の rails を.bundleディレクトリにインストールした。
  • .bundleにインストールされた rails を使って、bundle installをスキップした上でsampleというプロジェクトを作成した。

という状況です。

3. 用の済んだ仮rails 関連のファイルをすべて削除する。

sampleプロジェクトを作ることができたので、仮の rails はもういりません。なので、Gemfileたちと.bundleディレクトリを削除してしまいます。

$ rm -f Gemfile*
$ rm -rf .bundle

これで、仮の rails に関するファイルはすべてキレイさっぱり無くなって、sampleプロジェクトだけ残りました。

$ ls
sample

4. 作成済みの sample プロジェクトのディレクトリへ移動し、配下のディレクトリを指定して bundle install を実行する。

あと一歩です。

いよいよsampleディレクトリに入ります。

$ cd sample

で、rails s で起動したいところですが、先ほどrails newする時に--skip-bundleオプションをつけたので、gem がまだインストールされてません。肝心の rails さえもどこにもない状態です。

一旦ここで思い出してください。今回やりたかったのは、「プロジェクト内に gem をインストールする」ということです。

ということで、最初に仮の rails をインストールしたのと同様に、(今度はsampleディレクトリ配下という点が違います!)--pathオプションを使ってグローバルではなく、 プロジェクト内にvendor/bundle/というディレクトリを作って、そこへ gem をインストールします。

$ bundle install --path vendor/bundle/
Fetching gem metadata from https://rubygems.org/
・
・
・
Fetching version metadata from https://rubygems.org/
・
・
・
Installing rails 5.0.0
Installing sass-rails 5.0.5
Bundle complete! 15 Gemfile dependencies, 63 gems now installed.
Bundled gems are installed into ./vendor/bundle.

これで目的のRails環境を構築することができました!

5. 環境完成。rails s で起動できる。

さー起動してみましょう。

$ bundle exec rails s
=> Booting Puma
=> Rails 5.0.0 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
DEPRECATION WARNING: Sprockets method `register_engine` is deprecated.
Please register a mime type using `register_mime_type` then
use `register_compressor` or `register_transformer`.
https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
 (called from block (2 levels) in <class:Railtie> at /Users/utano320/Develop/Test/ruby/sample/vendor/bundle/ruby/2.3.0/gems/sass-rails-5.0.5/lib/sass/rails/railtie.rb:57)
DEPRECATION WARNING: Sprockets method `register_engine` is deprecated.
Please register a mime type using `register_mime_type` then
use `register_compressor` or `register_transformer`.
https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
 (called from block (2 levels) in <class:Railtie> at /Users/utano320/Develop/Test/ruby/sample/vendor/bundle/ruby/2.3.0/gems/sass-rails-5.0.5/lib/sass/rails/railtie.rb:58)
Puma starting in single mode...
* Version 3.5.2 (ruby 2.3.1-p112), codename: Amateur Raccoon Rocketry
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:3000
Use Ctrl-C to stop

Rails 5 になって変わってますね。非推奨メソッドのワーニングとか出てますけど、今回はとりあえず起動すればOKなので、細かい点はスルーします。

ブラウザでhttp://localhost:3000とURLを入力すると、次のような画面が表示されるはずです。

Ruby on Rails 5 デフォルト起動画面

なんかこのデフォルト画面いいですね。

関連記事