Vagrantでローカルの仮想マシンにRStudioServer環境を作る

## はじめに
### 前振り
ローカルで仮想環境を構築し、その中でRStudio Serverを稼働することで、ブラウザでRStudioを使えるようにすることを目指します。また、これをVagrantで自動化させます。

RStudioはクロスプラットフォームでWindows, Mac, あるいはUbuntuなどのLinuxの主なディストリビューション向けにデスクトップアプリケーションが準備されています。しかしながらこれらのデスクトップ版では、少なからず気になる点があります。

まずWindows版では文字コード問題です。RStudio(や一部Rのパッケージ)ではUTF-8を念頭に作られており、私の周りでもよく問題が発生しています。これはもうWindowsでR/RStudioを利用すれば避けられない問題となるでしょう。

Macでは主にWindowsとの互換が問題になることが多くなります。日本においてはWindowsユーザーが圧倒的に多く、データやファイルのやり取りでトラブルがしばしば発生します。

これらを解決するなら、「WindowsやMac上でUbuntuなどの仮想マシンを立ち上げその上で実行する」という手段があります。これにより上記2つの問題は解決できるのですが、インプットメソッドの関係で、Ubuntu14.04以降ではRStudio上で(そのままでは)日本語入力ができません。14.04なら回避する方法がなくもないのですが、今後この問題が解決する見込みは不明です。

以上より、最終的に冒頭で述べた手段で解決できるのではないかと考えました。この記事ではWindows8.1とMacについて説明します。

### メリットとデメリット
#### メリット
- プラットフォームの違いを吸収する
- さよならSJIS
- (自動化すれば)構築作業がシンプルで再現性が保てる
- なんかまずくなればすぐデストローイ
- 環境の共有がしやすい 等

#### デメリット
- 仮想化の知識が必要
- デスクトップ版よりもスタートさせるのに手間がかかる
- マシンにそれなりの性能が必要

### 想定読者と限界
普段RStudioを利用しているけど上述のデメリットで苦労している**インフラとかそういうのに詳しくない人**を対象者として想定しています。よって環境構築であまりいろんなものを使いたくないと思い、Vagrantを使っていますがAnasibleやDocker等を利用していません。シンプルさと抵抗感を軽減させるためと、**私がまだよくわかってないから**です。スクリプトが汚いのは私の仕様です。あとローカル限定です。ご了承ください。

なお、苦労を感じてなければこの記事を読むよりも[2月12日発売のR言語徹底解説](http://www.kyoritsu-pub.co.jp/bookdetail/9784320123939)を購入して読みましょう。またエンジニアの方にとってはこの内容は大したことないと思いますのでこの記事を読むよりも[2月12日発売のR言語徹底解説](http://www.kyoritsu-pub.co.jp/bookdetail/9784320123939)を購入して読みましょう。

## 前準備
### ターミナルの準備
まず、多くの作業がターミナルと言われるものが必要です。

#### Windows8.1の場合
Windows8.1ではPowerShellというのがあるのですが、厳しいです。以下今回私が導入したものです。以下の記事を参考に作ってます:

- http://qiita.com/Ted-HM/items/9a60f6fcf74bbd79a904

まずはMSYS2をダウンロードしてきます:

- http://sourceforge.net/projects/msys2/

64bit版をDLしてそのままインストールしました。そのままなら`C:\msys64\msys2_shell.bat`で起動するはずです。あとは先ほどの参考記事をもとに設定します:

```
$ update-core
# 終わったら一度シェルを閉じて再度開く
$ pacman -S bash # 色々聞いてくるので確認しながら個別でインストール
$ pacman -Syu # (多分)すでに入ってるパッケージの更新作業。gccもきてた
$ pacman -Sl # インストールしてるライブラリ一覧が表示されるけど、量が多すぎる。
# その他必要に応じて入れていけばOK
```

おそらく利用するでしょうから、試しにgitを入れてみます:

```
$ pacman -S git
```

あと、このままだと環境変数がうまくいってないっぽいので、PATHを`.bash_profile`に書き込んでください。

```
$ echo 'export PATH=/mingw64/bin:$PATH' > $HOME/.bash_profile
```

上記に関しては以下の記事を参考にしました:

- http://qiita.com/nana4gonta/items/717a4508fa585a454690

これでとりあえずOKです。ただし、この場合`/`(ルートディレクトリ)はmsmy2のディレクトリになるので注意してください。なお、Windowsのユーザーディレクトリに移動したい場合は以下の様な感じにコマンドを入力すればOKです:

```
$ cd /c/Users/(ユーザー名)
```

その他のコマンドについてはUNIXコマンドを検索して調べてみてください。

#### Macの場合
標準で**Terminal**というアプリケーションが入っていますので、それでOKです。

### VirtualBoxとVagrantのインストール
今回の仮想環境を構築するのに必要なソフトを入れていきます。最低限必要なのはVirtualBooxとVagrantなので、以下の2つを参照してください:

- https://www.vagrantup.com/
- https://www.virtualbox.org/

それぞれで、該当するOSの最新版をダウンロードしてそのままインストールしてください。Winの場合、Vagrantをインストールすると再起動を求められるかも知れません。その時は再起動してください。

## 仮想環境でマシンを構築
以降は(基本)WinとMacで共通です。ターミナルアプリで作業します。

### ボックスファイル(.box)のDLと追加
仮想マシンを作るためにはそのベースになるものが必要です。今回は仮想マシンの元となるboxファイルを持ってきて、それを利用します。

- https://atlas.hashicorp.com/boxes/search

ここからほしいboxを選んでURLをコピーしておき、Vagrantにこのボックスを登録・追加します。基本手続きはターミナルで以下の通りにコマンドを入力します:

```
$ vagrant box add {title} {url}
```

`vagrant box add`はコマンドで「vagrantさん、boxをadd(追加)しておくれ」という命令です。`{title}`はそのボックスの名前です。`{url}`は先ほど選んだboxのURLとなります。

今回はUbuntu公式の14.04を持ってくることにしました。理由は**私がUbuntuが好きだから**です。box名は`ubuntu1404`としてます:

```
$ vagrant box add ubuntu1404 https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box
```

マシンのベースになるんですから数百MBにもなるファイルです。結構時間かかります。あと**テザリングとか通信制限がある状況でやろうとするとあっという間に終わります**。この後も結構ダウンロードするデータがあるので、通信制限のない安定した回線で作業することをオススメします。

### 仮想マシンの作成
まずはマシンの場所を確保するため、vagrant用のディレクトリ(フォルダ)を準備してvagrantの初期化します。

#### Windowsの場合
自分が操作しやすい場所にvagrant用のディレクトリを作成して構いません。今回は`/c/Users/(ゆーざー名)`のディレクトリにvagrant用のディレクトリを準備することにしました:

```
$ mkdir -p /c/Users/(ユーザー名)/Vagrant/ubuntu1404
$ cd /c/Users/(ユーザー名)/Vagrant/ubuntu1404/
$ vagrant init ubuntu1404
```

一行目の`mkdir`で指定したパスの場所にディレクトリ(フォルダ)を作成しています。二行目でその作成したディレクトリに移動し、三行目の`vagrant init`で初期化しています。その後ろにある`ubuntu1404`というのは先ほどvagrantに登録したboxの名称です。

このコマンドを実行すると、このディレクトリに`Vagrantfile`というファイルが作成されます。これが仮想マシンの設定ファイル(設計書みたいなもの)となります。

#### Macの場合
基本Windowsの場合と同じです。ただディレクトリ構造がWinとは違いますので、ディレクトリのパスには気をつけてください。

```
$ mkdir -p ~/Vagrant/ubuntu1404
$ cd ~/Vagrant/ubuntu1404/
$ vagrant init ubuntu1404
```

### 仮想マシンの起動
さっそくでは仮想マシンを起動させましょう。構築して起動するには…先ほどのディレクトリでこの一行です:

```
$ vagrant up
```

これで起動完了。これだけで面倒な設定などしなくてもマシンができます。詳細を設定するには先ほどの`Vagrantfile`を色々編集する必要がありますが後述します。

なおマシンをデストローイするときには、このマシンのディレクトリで以下のコマンドでOKです:

```
$ vagrant destroy
```

### 仮想マシンにsshログイン

このままではこの仮想マシンを操作できないので、sshでログインします。sshとは、暗号や認証技術を利用してリモートコンピュータと通信するためのプロコトルで、ターミナルでリモート先のマシンを操作するときにひたすら使います。詳しい説明はググってください。

Vagrantで作ったマシンにsshでログインするには、このマシンのディレクトリで以下のコマンドを:

```
$ vagrant ssh
```

ssh関連の設定をいじってなければこれで入れるはずです。通常のsshでログインするには、IP周りの設定を確認してログインしてください(特にポート番号)。ssh周りをいじってなければ以下のとおり。

```
$ ssh -p 2222 vagrant@127.0.0.1
```

この場合、初回はRSA鍵を登録してくるか聞いてくるかと思います。

## 仮想マシンにRとRStudioServer導入
**追記(2016/02/06)**: コメント・アドバイスを受け修正しました。ありがとうございました。

RStudioServerを使えるようになるまでさっくりとやってみます。なお確認ですが、上記の通りに構成するとこの仮想マシンはUbuntu14.04(trusty)のServer版となります。


### Rのインストール
まずは仮想マシンにRをインストールします。UbuntuにRをインストールする手順については[こちら](https://cran.r-project.org/bin/linux/ubuntu/README.html)を参照してください。Ubuntu14.04でそのままRをインストールすると、ちょっと古いのが入ってしまいます。手動で新しいのを入れていくという手段もありますが、もう最新版を持ってくるようにリポジトリをaptのソースリストに追加します[^1]。

[^1]: これは私の好みです。

```
$ echo "deb https://cran.rstudio.com/bin/linux/ubuntu trusty/" | \
  sudo tee -a /etc/apt/sources.list.d/cran.list
```

次はgpg鍵を登録するため端末で以下を実行します。**よく転がってる方法だとfirewallの設定でポートブロックされる**ので、以下のように`hkp://~`でポート指定することに注意してください。

```
$ gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys E084DAB9
$ gpg -a --export E084DAB9 | sudo apt-key add -
```

ここまでくれば準備完了です。Rのインストールを行います:

```
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install r-base-dev
```

結構な量のライブラリがインストールされます。もしインストールされない場合は、登録したCRAN mirrorサイトや公開鍵に入力ミスがないか確認してください。これでRの準備はOKです。

### RStudioServer(preview)の導入
RStudio Serverには安定版とプレビュー版があります。安定版でも問題ないのですが、プレビュー版は新機能が盛りだくさんで楽しいです。今回はこのプレビュー版(執筆時0.99.876)を導入することとします[^2]。

[^2]: 完全に私の好みですが、新機能がすごいのでぜひ試してみてください。preview版がおいてあるところは[こちら](https://www.rstudio.com/products/rstudio/download/preview/)です。

RStudioServerを入れるには、以下のコマンドを実行してください。`0.99.876`はプレビュー版のバージョンです。適宜修正してください:

```
wget https://s3.amazonaws.com/rstudio-dailybuilds/rstudio-server-0.99.876-amd64.deb
sudo dpkg -i *.deb
sudo apt-get -f install rstudio-server
```

一行目でRStudioServerをダウンロードし、二行目でインストールしています。そして三行目で依存パッケージをインストールしています。インストールが終わったら、これで仮想マシンにRStudioServerがはいりました。

### Vagrantfileを修正してRStudioServerを起動
実はこれだけだとまだ使えません。仮想マシンのネットワーク設定を変更する必要があります。ここからの作業は仮想マシンではなく手元のマシン上で行いますので、一度仮想マシンから出ます:

```
$ exit
```

これで仮想マシンから手元のマシンに戻ってきます。次に、ポートフォワーディング設定をするために`Vagrantfile`を編集します。このファイルは、`vagrant init`を実行したディレクトリにあります。このファイルを任意のテキストエディタで開いてください。

開いたら、コメントアウトされてる`"forwarded_port"`からコメントアウトを外し、以下の設定を加える(詳しくは[こちら](http://notchained.hatenablog.com/entry/2014/04/27/141927)だけど、微妙に標記が違うので注意。あとhost側のポート番号は任意。)

```
config.vm.network "forwarded_port", guest: 8787, host: 1111
```

編集したら上書き保存して閉じてください。これで設定は完了ですので、仮想マシンを再起動します:

```
$ vagrant reload
```

### アクセス!!
これで準備完了です。あとはブラウザでログインしましょう。末尾はVagrantfileで設定したポート番号となります。

```
http://localhost:1111
```

ログイン画面がでたら、ユーザー名は`vagrant`、パスワードは`vagrant`でOKです[^3]。ようこそRStudioServerへ!

[^3]: vagrantで構築した場合のデフォルト値です。Ubuntu上でユーザーを追加すればそれでも可能です。

## 上記作業を自動化+α
`vagrant up`をする前に、Vagrantfileに必要事項を編集しておけば、仮想マシンを建てたあとに自動的に色々実行させることができます。これをきっちり作っておくことで手作業が減り、安定して同環境のR環境を準備できるようになります。

### Vagrantfile
私の方で、とりあえず作ってみました。  
**追記(2016/02/06)**: コメント・アドバイスを受け修正しました。ありがとうございました。

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

# 通常はこちらを使って下さい
# config.vm.box = "ubuntu/trusty64"

# この記事の上の方で登録したboxを利用するため"ubuntu1404"としています
  config.vm.box = "ubuntu1404"

# 共有ディレクトリ設定(コメントアウトしてます)
 # config.vm.synced_folder "../data", "/vagrant_data"

# ポートフォワーディング設定
  config.vm.network "forwarded_port", guest: 8787, host: 1111

#仮想マシンのメモリ設定
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
  end

# 以下プロビジョニング用スクリプト
$script = <<SCRIPT
echo "deb https://cran.rstudio.com/bin/linux/ubuntu trusty/" > /etc/apt/sources.list.d/cran.list
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys E084DAB9
sudo apt-get update
sudo apt-get install -y r-base r-base-dev

## for install devtools, rvest(libxml2)
sudo apt-get install -y libcurl4-openssl-dev libssl-dev libxml2-dev

## r-packages install
sudo R -e "install.packages('devtools', repos = 'https://cran.rstudio.com/', dep = TRUE)"
sudo R -e "install.packages('ggplot2', repos = 'https://cran.rstudio.com/', dep = TRUE)"
sudo R -e "install.packages('dplyr', repos = 'https://cran.rstudio.com/', dep = TRUE)"
sudo R -e "install.packages('tidyr', repos = 'https://cran.rstudio.com/', dep = TRUE)"
sudo R -e "install.packages('stringr', repos = 'https://cran.rstudio.com/', dep = TRUE)"
sudo R -e "install.packages('rvest', repos = 'https://cran.rstudio.com/', dep = TRUE)"
sudo R -e "install.packages('rmarkdown', repos = 'https://cran.rstudio.com/', dep = TRUE)"
## rstudio-server install
wget https://s3.amazonaws.com/rstudio-dailybuilds/rstudio-server-0.99.876-amd64.deb
sudo dpkg -i *.deb
sudo apt-get -f install rstudio-server
rm *.deb
SCRIPT

# スクリプト実行
  config.vm.provision "shell", inline: $script

end
```

内容的に同一の内容を[こちらのgist](https://gist.github.com/kazutan/9ceb03e3705e85a53f74)に置いています[^4]。このVagrantfileが置いてあるディレクトリ上で`vagrant up`を実行すれば、一気にRStudio Serverのインストールまで終わります。さらに、私がよく使うパッケージも合わせてインストールするようにしています。

[^4]: gistの分は自分の都合で更新していく可能性が高いです。

### 注意事項

- 私の手元では無事に走りました…が、如何せん初めてのVagrantfile、初めてのprovisionなので不安です。
- `vagrant up`すると相当ながいことターミナルに出力が吐き出されます(特にシェルスクリプト部分)。実際に利用するとなったら、エラーのみ標準出力させるよう修正したほうがいいです。
- もっとスマートな書き方があると思うのですが、私のスキルはこの程度、ということです。
- 共有ディレクトリ設定`# config.vm.synced_folder "../data", "/vagrant_data"`は自分が管理しやすいところにしておいた方がいいでしょう。OSによってパスの書き方が変わるので注意して**ググってください**。
- 「私に必須のパッケージがないじゃないか!!」という方は、構築した後に入れるか上述のスクリプトを参考に修正してください。  
ただパッケージによってはUbuntuのリポジトリからライブラリを持ってくる必要があります。その時はRのインストール処理する行の前にある部分で書いてください。
- **(2016/02/23追記)**このままだと、Plotsで日本語が文字化けします。以下の記事を参考に日本語フォントをインストール&RStudioServerを再起動してください:  
http://masato.github.io/2014/08/13/rstudio-exercise-part1/

## ToDo
- Vagrantfileをもうちょっとマシにする
- Ansibleであそびたい
- 俺々boxファイル作成→クラウド上に設置

Enjoy!