DockerとJupyterをデータ解析・可視化関連ワークショップの実行環境配布手段にする

# 容易に再現可能なデータ解析と可視化の環境

![](http://cl.ly/aPle/jupyter-sample1.png)

私は仕事で各種ツールの使い方のレクチャーを行うこともあるのですが、この時に頭が痛い問題は、こちらで用意したサンプルやチュートリアルの実行環境の配布方法です。通常一つのデータ解析ワークフローを実行する場合、素の状態のPythonやR実行環境だけで済むことは稀です。多くの場合、Pythonならば[SciPy / NumPy / Pandas](http://www.scipy.org/)、生物学者向けのRを使ったレクチャーならば[Bioconductor](http://www.bioconductor.org/)といった定番のツールをインストールし、更に目的のアプリケーションを実行するために追加のライブラリをインストールする必要があります。もちろん全てを詰め込んだ仮想マシンファイルを配布することも出来ますが、自前で配布するフィルサイズが増えたり、その仮想マシンを作成するのに必要な手順をどう保存/自動化するのかといった問題があります。

幸い最近は各種ツールを組み合わせることにより、こういった比較的複雑な作業をこなすための環境をまるごと再現する事も可能になってきました。本稿は、私が先日[ある学会のチュートリアル](http://vizbi.org/2015/)で試した実験的手法を共有することを目的としています。問題点の指摘や改善点などをフィードバックいただけるとありがたいです。__この手法は、データ解析や可視化の各種ワークショップやチュートリアルに使用することを想定していますが、多少修正すれば、ハッカソンのためのスターターキット的に使うことも可能です__。

# 参加者の環境を揃える
何らかのチュートリアルを行う場合、参加者の環境を統一する必要があります。これは、全てのマシンを予め主催者側で用意できる場合は良いのですが、マシン持込の場合、ソフトウェアの依存関係が複雑だったり、インストールそのものが容易でない場合はかなり厄介な問題です。当日になって「私のマシンでは動いたのですが...」ということも頻繁に起こります。これを解決するために、以下の様なツールを組み合わせました。

## GitHub
環境やコードを配布する手法としてGitHubを利用します。仮想マシンの配布の場合は、ファイルの大きさが問題になりこれは無理ですが、次に紹介するDockerを使うことによってこれを回避できます。

## Docker

![](http://cl.ly/aPqp/docker.png)

依存関係も含めた解析と可視化のための環境配布には[Docker](https://www.docker.com)を利用します。[Docker Hub](https://registry.hub.docker.com/)を通じて大量の便利な環境が配布されており、これらをそのまま使うことも出来ますが、実際にはそこに多少の依存関係を追加することになります。公開されている環境を継承して新しいものを構築出来るというのが非常に大きなアドバンテージです。

## IPython Notebook / Jupyter
今回はPythonを用いたグラフデータ可視化の入門を行ったので、[IPython Notebook](http://ipython.org/notebook.html)をサンプルコード配布の手段にしました。IPython Notebook (次期バージョンからは、ノートブック部分と言語カーネル部分は独立して、ノート部分は[Jupyter](http://jupyter.org/)と呼ばれます)についてはたくさんの記事がありますので、そちらを参照して下さい。また、IPythonプロジェクト自身が管理しているDocker Hubレポジトリがあり、そこに[SciPy, NumPy, Pandasなどを予めインストールしてあるイメージ](https://registry.hub.docker.com/u/ipython/scipyserver/)が用意されていますので、これを親に指定してDockerfileを書くことにより、最小限の追加で済みます。

# 実際の手順

## 対象とするオーディエンス
今回は研究所や政府関連機関で働くような人々がオーディエンスの中心でした。つまり手段としてプログラミングは行うが、専業プログラマではない人々です。ですからプログラマを対象とする場合は、以下のステップの幾つかは省略可能だと思います。

## 1. 受講者向けのアナウンスとソフトウェアのインストール
レクチャーの中で本質的な部分に集中しインストールで時間を潰さないために、まず参加者に対して必要なソフトウェアを予めラップトップにインストールしてもらうよう連絡しておきます。今回の手法の利点は、どんなワークフローに対しても以下の２つをインストールしてもらうだけで対応できる点です。

### Git
GitHubを通じて必要な物を配布するため、これは避ける事が出来ませんでした。これも一つのオーバーヘッドですが、さすがにこの部分を簡略化することは難しいので、ここだけは今後も使える知識として覚えてもらいます。しかし具体的には既存のGitHubのレポジトリをforkしてcloneできれば、とりあえずは問題無いです。

#### Githubのアカウント
今回は幸い全員がアカウントを持っていたのでスムーズに進みましたが、これも忘れないように予めアカウントを取得しておく事を伝えるべきでしょう。

### DockerとBoot2docker
Dockerのインストールは、ある程度のコンピュータに関するリテラシーのある人ならば簡単に行えるはずです。今回は英語での講義でしたので、このビデオを参考にするように伝えました。有料ですが、インストール解説を含む最初の３つのチャプターは無料で閲覧可能です:

* [Introduction to Docker](http://shop.oreilly.com/product/0636920035732.do)

また、公式ドキュメントも充実していますので、それを参照するようにすれば、ほぼ間違いなくセットアップできるはずです。大半の参加者はWindowsかMacと言う場合が多いので、それにLinuxを加えた３つのプラットフォームでサンプルをテストしてみることが重要です。今回は参加者の9割ほどがMacだったので、個人的には楽でした。

## 2. サンプルコード配布用GitHubレポジトリの用意
まずは大きなデータファイルを除く、レクチャーに使うすべてのものを入れる容器としてGitHubのレポジトリを用意します。そこに必要なものを詰め込みます。

今回のようなレクチャーの場合、レポジトリの基本構造は以下のようになると思います。

```bash
~/g/vizbi-2015 git:master ❯❯❯ tree
.
├── Dockerfile
├── LICENSE
├── README.md
├── graph-tool-pub-key.txt
└── tutorials
    ├── Lesson_0_IPython_Notebook_Basics.ipynb
    ├── Lesson_1_Introduction_to_cyREST.ipynb
    ├── Lesson_2_Graph_Libraries.ipynb
    ├── Lesson_3_Visualization.ipynb
    ├── answers
    │   └── Lesson_1_Introduction_to_cyREST_answer.ipynb
    ├── data
    │   ├── galFiltered.gml
    │   ├── sample.dot
    │   └── yeast.json
    └── graph-tool-test.ipynb

3 directories, 13 files
```

具体的な内容を見ていきます。

#### Dockerfile
レクチャーで使うイメージを設定するためのものです。厳密に言えば、これがなくてもDocker Hubの方へイメージをデプロイしておけば問題ないのですが、後で参加者が独自の拡張をしたくなった場合、直ぐに自分で新しいビルドを作れるように一緒に配布するのがよいでしょう。

#### README.md
まずコンテナを実行できるところまでの手順を、クイックスタートガイドとして書いておきましょう。詳細ドキュメントへのリンクも必要です。頻繁に修正することになるので、ドキュメントはGitHubのWikiなどを利用します。

#### ノートブック専用のディレクトリ (___tutorials___)
トップレベルのディレクトリをスッキリさせるために、.ipynbファイルは一つにまとめておくのがよいでしょう。ここに実際のワークショップで使う実行可能なノートを保存します。

#### データ用ディレクトリ　(___tutorials/data___)
ワークショップで利用するデータがごく小さいものならば、それも一緒にレポジトリに入れてしまいましょう。何をもって大きいとするかはいろいろな意見があると思いますが、メガバイト単位のデータになった場合は、GitHubでの管理よりも別の配布手段を考えるのが無難です。ギガバイト単位の場合は、原始的ですがUSBメモリの利用が安全です。開始前に一人ずつコピーして回してもらいましょう。


## 3. 実際の環境でのテスト
ここでは、気軽に同一の環境を複数の人が共有できるという点に重点を置いているので、深くDockerについて学ぶようなことは行いません。あくまでポータブルで拡張可能な実行環境という点を伝えられれば十分です。しかし、以下の概念だけはしっかり伝えないと混乱のもとになります。

### Data Volumes
どんどんノートの内容を自分で書き換えることによって学ぶのを想定していますので、-vオプションでホストのData Volumeをマウントして使います。必ずこのセクションは読んで、まずこの機能の詳細を把握して下さい。

* [Managing Data in Containers](https://docs.docker.com/userguide/dockervolumes/)
* [Mount a Host Directory as a Data Volume](https://docs.docker.com/userguide/dockervolumes/#mount-a-host-directory-as-a-data-volume)

cloneしたディレクトリに入ってもらい、そこで以下ののようなオプションを付けて実行してもらうことにより、コンテナ側からのエディットも、ホスト側からのファイルの追加などもリアルタイムに反映されることを確認してもらいます

```
-v $PWD:/notebook
```

__注意: Boot2Dockerを利用している場合、-vオプションでは/Users (Mac OSX)もしくはC:\Users (Windows)ディレクトリしかマウントできません__。これ以外に指定して現在のディレクトリをマウントできずにハマる人が居ましたのでご注意を。Linuxの場合は制限はありません。

そして全てのノートブックを実行してみて問題がないか確認します。クイックスタートの通りに作業して、エラーなく実行できれば問題ありません。

## 4. 当日
レクチャーはスライドとノートブックを行き来することになると思います。仮想デスクトップ(Macならば[Mission Control](https://support.apple.com/ja-jp/HT204100))を使って、スライド用のデスクトップとノート実行用のデスクトップを切り替えながら行うと便利です。

内容はあまり汎用的でないので参考にならないかもしれませんが、今回のスライドとノートはこちらになります：

* [VIZBI 2015 Tutorial: Cytoscape, IPython, Docker, and Reproducible Network Data Visualization Workflows](http://www.slideshare.net/keiono/vizbi-2015-tutorial-cytoscape-ipython-docker-and-reproducible-network-data-visualization-workflows)
* [ノートブックとDockerfile](https://github.com/idekerlab/vizbi-2015)


# 問題点
実際にこの手順を試してみて、いくつか問題に気づきましたのでメモしておきます。

### Dockerのインストール
Dockerのインストールはかなり簡単ですし、よく整備されたドキュメントやビデオも出回っていますが、それでもインストールに躓く参加者がいました。完全に誰でもインストールできるというのは、インストーラーのダブルクリック、もしくはbrew/apt-getなどのパッケージマネージャで設定ゼロで使える状態でないとダメなようです。

今回の場合、boot2dockerがらみで.bashrcなどにexportステートメントを追加して幾つか環境変数を追加しておく、と言う部分が分からなかった人がいました。

### 必要なスキルと最終的なゴール
残念ながら前提知識が欠けていたため、一人だけ全くついて来られない方が居ました。こういったミスマッチは残念ながら起こりえるので、最終的なゴールと絶対に必要な知識だけは周知徹底しておくことが重要です。

### イメージのpull
ご存知の通り、Dockerの実行自体は非常に軽いですが、初めて実行する時には必要な依存関係を全てDocker Hubのレポジトリからダウンロードするために非常に時間がかかります。このため、参加者に宿題として配布したイメージをrunコマンドで実行だけしておいて欲しいとお願いしたのですが、それが必要な意味をしっかり伝えなかったため、会場でコンテナをスタートさせるのに非常に時間がかかる方も居ました。今回は研究所のネットワークがそれなりに早かったので何とかなりましたが、帯域制限でそもそもこれが不可能な場合もあります。Dockerのインストールドキュメントではubuntuのコンテナのシェルにログインするあたりを動作確認としていますが、それに加えて、当日使うイメージの実行を必ず予め行うように伝えるべきです。

# まとめ

![](http://cl.ly/aQUr/linear-sorted-1.png)

この手法を使うのはまだ初めてだったので、うまくいくかどうか不安でしたが、なんとか無事に終わりました。今後もチュートリアルなどを通じて、さらに効率のよい、確実性の高い方法を模索していこうと思います。