R使いのためのDocker「Rocker」を使ってみる(Windows)

Rcppの開発者のひとが、R用のDockerイメージをつくるプロジェクトをやっている。その名もRocker。これが公式に採用されたよワーイ!みたいなブログを見かけたので、ちょっとためしてみました。

Rocker is now the official R image for Docker

結論から言えば、個人的にはおもしろいなーと思うんですがDockerはいろいろ慣れないと難しいこともあるので他の人に勧められるかといえば微妙です。市井のR使いにとってはまだ選択肢ではないかなという気がします。

※ちなみに今は、vagrantにRStudioを立てて使っています。
WindowsでvagantにRStudio Serverを立てる - Technically, technophobic.

Dockerとは

Dockerは、コンテナ型仮想化の環境です。コンテナは、VMのように使える、より軽量な仮想化の方式です(雑な説明ですみません…)。公式の説明では以下のようになっています。

Docker is an open platform for developers and sysadmins to build, ship, and run distributed applications.(https://www.docker.com/whatisdocker/)

アプリケーションを開発して配ったりデプロイしたりする開発者やインフラエンジニア向けのプラットフォームですよ、と。

Dockerでは、コンテナの構成をDockerfileというファイルに書いて、それをビルドすることで誰でも同じ環境を手にすることができます。(厳密にいえばパッケージのバージョンとかはタイミングによって違うので完全に同じとはいえないかも)

例として、RockerのDockerfileを見てみましょう。話が前後しちゃいますけど。

https://github.com/rocker-org/rocker/blob/master/debian/r-base/Dockerfile

Dockerfileの文法はよく分からなくても、なんかユーザを追加したりロケールを設定したりパッケージを入れたり、色々やってる雰囲気が分かると思います。

これをやってください、というのは大変です。コマンドを打ち間違えたり、その人ローカルの環境固有の落とし穴に引っかかったり、などなど。

それを、Dockerだと、ひとこと「docker pullしてください」といえば済んでしまいます。パッケージを開発したりとか、研究者間で同じ環境を揃えないといけない、なんていうときはDockerは便利です。

Rockerとは

Rockerとは、R用のDockerイメージをつくるプロジェクトです。今のところ、以下のDockerfileが公開されています。

  • r-base (base package to build from)
  • r-devel (base plus R-devel from SVN)
  • rstudio (base plus RStudio Server)
  • hadleyverse (rstudio + Hadley's packages, LaTeX)
  • ropensci (hadleyverse + rOpenSci packages)
  • r-devel-san (base, SVN's R-devel and SAN)

hadleyverseというコンテナ名に吹きましたw 直截的すぎるやろ。

新しいコンテナが増えれば、以下に追加されるようです。

新しいコンテナつくってほしい!とかいう要望はIssueに投稿したり、自分でプルリクエストを投げたりするといいみたいです。詳しくは以下。

How to contribute · rocker-org/rocker Wiki · GitHub

Windowsで使ってみる

DockerはLinux用のシステムです。Windowsで使うには、Dockerホスト用のLinux VMを立てる → その上でDockerコンテナを動かす、というステップを踏む必要があります。

めんどくさいし、たぶん二重にオーバーヘッドが発生しています。が、まあそんなことは気にせず先に進みます!

boot2docker

最近Windows用のDocker CLIも出ましたが、これを使うには別途Dockerホストを立てる必要があります。手元で使うならboot2dockerを入れるのがお手軽です。

以下の手順に従ってインストールします。

Docker Docs

boot2dockerは、

をセットアップしてくれます。

ハマったところ

Boot2Docker Startのショートカットをダブルクリックしてもテキストエディタが立ち上がるだけでした。.shという拡張子とアプリケーションの紐付けを変える必要があります。

「既定のプログラム>ファイルの種類またはプロトコルのプログラムの関連付け」を選び、.shのファイルをbashに関連付けます。bashのパスはたぶん、C:\Program Files (x86)\Git\bin\bash.exeとかになっていると思います。

DockerホストにSSHする

Git Bashだとコマンドがコピペできないので不便です。Puttyとかのsshクライアントを使うには、IPとポートは

ip: 192.168.59.103
port: 2022

です。たぶん。(IPは違ったら、boot2docker ipと打てばいいらしいです)。ユーザ名とパスワードは以下。

user: docker
pass: tcuser
(https://github.com/boot2docker/boot2docker#ssh-into-vm)

Rockerのコンテナを起動する

とりあえずr-baseを動かしてみる

Dockerイメージを落としてくるにはdocker pullコマンドを使います。

$ docker pull r-base

イメージの一覧を見るにはdocker imagesコマンドです。

$ docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
r-base               latest              42bb2d6f4792        4 weeks ago         522.5 MB

コマンドを実行するにはdocker run イメージ コマンド...です。

$ docker run r-base R --version
R version 3.1.2 (2014-10-31) -- "Pumpkin Helmet"
Copyright (C) 2014 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)
...

おお、R入ってますね! コンテナの中でインタラクティブにコマンド打ちたいときは、以下のようにします。

$ docker run -i -t r-base /bin/bash

まあr-baseはこんなものにして、次はいよいよhadleyverseを触ってみます。

DockerでRStudioを立ててみる

Hadleyさんのパッケージ全部入りのDockerイメージ、hadleyverseをpullしてきます。 r-base以外は公式イメージじゃないので、rocker/を付ける必要があります。

docker pull rocker/hadleyverse

外からアクセスできるようにするには、-pオプションでポートフォワードを設定します。

docker run -d -p 8787:8787 rocker/hadleyverse

これでもうRStudio Serverが立ち上がりました。http://192.168.59.103:8787にアクセスするとログイン画面が見えます。(IPは、DockerホストのIPです)。UsernameもPasswordもrstudioになっています。

f:id:yutannihilation:20140428003926p:plain

入っているパッケージは以下でした。dplyrggplot2stringimagrittrroxygen2knitrも、初めから入っています!

> library(dplyr)
> data.frame(installed.packages(), row.names = NULL) %>%
+  select(Package, Version) %>%
+  arrange(Package)
            Package   Version
1                BH  1.54.0-5
2     BiocInstaller    1.16.1
3             Cairo     1.5-6
4               DBI     0.3.1
5           Formula     1.1-2
6             Hmisc    3.14-6
7        KernSmooth   2.23-13
8            Lahman     3.0-1
9              MASS    7.3-35
10             MASS    7.3-35
11           Matrix     1.1-4
12              PKI     0.1-1
13               R6     2.0.1
14     RColorBrewer     1.1-2
15            RCurl  1.95-4.5
16          RJSONIO     1.3-0
17           RMySQL     0.9-3
18      RPostgreSQL       0.4
19          RSQLite     1.0.0
20          RSQLite    0.11.4
21  RSQLite.extfuns     0.0.1
22             Rcpp    0.11.3
23          SparseM      1.05
24          TH.data     1.0-5
25              XML  3.98-1.1
26          acepack   1.3-3.3
27       assertthat       0.1
28             base     3.1.2
29        base64enc     0.1-2
30           bitops     1.0-6
31             boot    1.3-13
32             brew     1.0-6
33          caTools    1.17.1
34            chron    2.3-45
35            class    7.3-11
36          cluster    1.15.3
37        codetools     0.2-9
38        codetools     0.2-9
39       colorspace     1.2-4
40         compiler     3.1.2
41       data.table     1.9.4
42         datasets     3.1.2
43         devtools     1.6.1
44        dichromat     2.0-0
45           digest     0.6.6
46           docopt       0.3
47            dplyr   0.3.0.2
48         evaluate     0.5.5
49          foreign    0.8-61
50          formatR       1.0
51          ggplot2     1.0.0
52        grDevices     3.1.2
53         graphics     3.1.2
54             grid     3.1.2
55           gtable     0.1.2
56           hexbin    1.27.0
57            highr       0.4
58        htmltools     0.2.6
59           httpuv     1.3.2
60             httr     0.6.0
61             jpeg     0.1-8
62         jsonlite    0.9.14
63            knitr       1.8
64         labeling       0.3
65          lattice   0.20-29
66          lattice   0.20-29
67     latticeExtra    0.6-26
68         lazyeval     0.1.9
69         lineprof       0.1
70         magrittr       1.5
71       manipulate 0.98.1091
72          mapproj     1.2-2
73             maps     2.3-9
74         maptools    0.8-30
75         markdown     0.7.4
76          memoise     0.2.1
77          methods     3.1.2
78             mgcv     1.8-4
79             mgcv     1.8-3
80   microbenchmark     1.4-2
81             mime       0.2
82         multcomp     1.3-8
83          munsell     0.4.2
84          mvtnorm     1.0-2
85             nlme   3.1-118
86             nlme   3.1-118
87             nnet     7.3-8
88     nycflights13       0.1
89         parallel     3.1.2
90             plyr     1.8.1
91              png     0.1-7
92            proto    0.3-10
93         quantreg      5.05
94            rJava     0.9-6
95         reshape2     1.4.1
96              rgl 0.94.1143
97        rmarkdown     0.3.3
98         roxygen2     4.1.0
99            rpart     4.1-8
100         rstudio 0.98.1091
101      rstudioapi       0.1
102        sandwich     2.3-2
103          scales     0.2.4
104           shiny  0.10.2.2
105              sp    1.0-16
106         spatial     7.3-8
107         splines     3.1.2
108           stats     3.1.2
109          stats4     3.1.2
110         stringi     0.4-1
111         stringr     0.6.2
112        survival    2.37-7
113           tcltk     3.1.2
114          testit       0.3
115        testthat     0.9.1
116           tidyr     0.2.0
117           tools     3.1.2
118           utils     3.1.2
119         whisker     0.3-2
120          xtable     1.7-4
121            yaml    2.1.13
122             zoo    1.7-11

手元で使うには向いてない点

まあこんな感じなんですが、Dockerはやっぱり手元でだけ使うにはコストに見合わない感があります。

パッケージを追加したりするのがめんどくさい

パッケージをインストールしたりしても、元のイメージには変更は反映されません。docker commitするなり、自分でDockerfileをいじるなりすればいいんですが、めんどくさいです。

データを保存する場所を別に用意しないといけない

上と同じく、色々データをつくったり変更したりしても、元のイメージには反映されません。別のボリュームを-vオプションでコンテナにマウントして使うことが推奨されています。詳しくはドキュメント参照。

Sharing files with host machine · rocker-org/rocker Wiki · GitHub

Docker Docs

ほっておくとコンテナの差分が溜まっていく

コンテナを立ち上げるたびに、その差分がつくられるので、いらない差分は消してやらないとディスク容量が馬鹿になりません。 (これベストプラクティスがよく分からなくて、思いついたらdocker rm $(docker ps -a -q)してるんですけど、なにかいい方法あるんでしょうか...?)

その他

Docker一般の話は、以下の翻訳記事が分かりやすいと思います。

まとめ

Dockerはやっぱまだ開発者向けのツールだと思います。そのうち違うようになるかもしれませんけど。 Reproducible Researchな人々の使用例が出てくるのを楽しみにしています。

とりあえず今は、Docker使ってますっていうと今風でかっこいい感じがあるので、JuliaとかPython勢に対してマウンティングしたい人とか使うといいんじゃないでしょうか(違


追記: 探してみたら、IPythonもIJuliaもDockerイメージありました。Rが時代から遅れてただけでした。すみません。。