Vagrantのprovisioningでrbenvを使ってrubyをインストールする


Vagrantのprovisionでshellを使ってrbenvを利用する場合、ログイン後のCLIとは異なる環境となる。
そのため、以下に記すような設定が必要となる。OSはUbuntu14.04

## 依存パッケージのインストール

まず`rbenv`および`ruby`をインストールするために必要なパッケージを`apt-get`でインストールする。
`config.vm.provision()` の引数で特に指定しない場合は **root** でスクリプトが実行される。そのため`$ apt-get install`などで`sudo`を指定する必要はない。

```ruby:Vagrantfile
config.vm.provision "shell", inline: <<-SHELL
  apt-get install -y build-essential libssl-dev
  apt-get install -y ruby-build
SHELL
```


## rbenvをインストールする

bashでインストールする場合は以下のようなコードとなる。`rbenv`自体のインストールは`git clone`がメイン。
この時 `privileged: false` を指定して **vagrantユーザー** で実行させる。
この設定がないと各ファイルの所有者や環境変数が **root** のものとなってしまい、意図したディレクトリにインストールされない。

`$ echo ...`の記述を`~/.bashrc`に追記することで、ログイン時に`rbenv`の初期化が行われ使用可能となる。この記述は`rbenv`を使う上で必須。

```ruby:Vagrantfile
# rbenvをインストール
config.vm.provision "shell", privileged: false, inline: <<-SHELL

  if ! [ -d .rbenv ]
  then
    git clone https://github.com/sstephenson/rbenv.git .rbenv
    git clone https://github.com/sstephenson/ruby-build.git .rbenv/plugins/ruby-build
    echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> .bashrc
    echo 'eval "$(rbenv init -)"' >> .bashrc
  fi
  
SHELL
```

## rbenvでrubyをインストールする

### rbenvの初期化

`rbenv`を利用する場合、前述のとおり **初期化が必須** となる。
ログインをして利用する場合 `~/.bashrc` に追記した内容がログイン時に実行されるのでCLIで`rbenv`を問題なく利用できる。
しかしプロビジョニング時は`~/.bashrc`を実行しないので、明示的に初期化が必要となる。これは`cron`などで使う場合も同様。

```bash
# この2行が初期化処理
export PATH="/home/vagrant/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
```

これを実行することで以降の `$ rbenv install` などのコマンドが利用可能となる。

### rbenvをvagrantユーザーで実行する

こちらも同様 `privileged: false` として **vagrantユーザー** で実行する必要がある。
rootで実行すると `$HOME` `$USER` といった環境変数はrootのものとなる。
そのため　`$ rbenv init -` の結果もrootのものとなってしまい、`rbenv`コマンドが正常に初期化されない。


```ruby:Vagrantfile
# install ruby by rbenv
config.vm.provision "shell", privileged: false, inline: <<-SHELL

  if [ -e .rbenv/bin/rbenv ]
  then
    export PATH="$HOME/.rbenv/bin:$PATH"
    eval "$(rbenv init -)"
    
    rbenv install -s 2.4.0
    rbenv rehash
    rbenv global 2.4.0
  fi
SHELL
```

以下が **root** での `$ rbenv init -` の出力。rootで実行されているので `export` などのパスがvagrantユーザーのものではない。

```bash
export PATH="/root/.rbenv/shims:${PATH}"
source "/usr/lib/rbenv/libexec/../completions/rbenv.bash"
rbenv rehash 2>/dev/null
rbenv() {
  typeset command
  command="$1"
  if [ "$#" -gt 0 ]; then
    shift
  fi

  case "$command" in
  rehash|shell)
    eval `rbenv "sh-$command" "$@"`;;
  *)
    command rbenv "$command" "$@";;
  esac
}

```



## まとめ

- シェルを実行するユーザーを意識する
- `rbenv` の初期化をおこなう

上記の2点がポイント。


```ruby:Vagrantfile
Vagrant.configure("2") do |config|

  # rubyをrbenvでインストールする
  # install package
  config.vm.provision "shell", inline: <<-SHELL
    apt-get install -y build-essential libssl-dev
    apt-get install -y ruby-build
  SHELL
  
  # install rbenv
  config.vm.provision "shell", privileged: false, inline: <<-SHELL
    if ! [ -d .rbenv ]
    then
      git clone https://github.com/sstephenson/rbenv.git .rbenv
      git clone https://github.com/sstephenson/ruby-build.git .rbenv/plugins/ruby-build
      echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> .bashrc
      echo 'eval "$(rbenv init -)"' >> .bashrc
    fi
  SHELL

  # install ruby by rbenv
  config.vm.provision "shell", privileged: false, inline: <<-SHELL
    if [ -e .rbenv/bin/rbenv ]
    then
      export PATH="/home/vagrant/.rbenv/bin:$PATH"
      eval "$(rbenv init -)"
      
      rbenv install -s 2.4.0
      rbenv rehash
      rbenv global 2.4.0
    fi
  SHELL

end

```