Google Colaboratory の ローカルランタイムへの接続

3/29 に突然、Colaboratory の接続にオプションが増えました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/38555/1aff2a31-54a2-a420-3bf7-26669d02d149.png)

下三角をクリックすると、「ローカル ランタイムに接続」が選べるようになっています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/38555/6a430002-c4c6-bc59-ff95-5154f03e55e9.png)

クリックするとこのようなダイアログが表示されます。「[こちらの手順](https://research.google.com/colaboratory/local-runtimes.html)」のページを見ると、Jupyter Notebook に繋げるようです。実行は、接続先のJupyter Notebookになりますが、保存されるのは、Googleドライブ上という仕組みのよう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/38555/179e33e8-d19b-d5f0-5173-473e60adf188.png)

では、Google Colaboratoryとそっくりの、Docker インスタンスを作ってみようというのが、この記事です。

なにが嬉しいのか？
==============

まぁ、ローカルでJupyter Notebookが動いているのに、わざわざ、Colaboratoryを使う意味は少ないはずです。
ですが、Colaboratoryで作ったNotebookを簡単にローカルで動かせるのは魅力かもしれません。
ざっくり、以下のようなメリットがあると思います

* Colaboratoryの方が、Jupyter Notebook よりも軽快で使いやすい（もっとも、Jupyter Notebook の Extensionを使いまくっている人には、便利では無いかもしれないが）
* ちょっと試すのは、Colaboratoryでやって、その後、長いタスクを試す時は、自宅のPCや、Google Compute Engine ・ AWS EC2等にインスタンスにつないで実行する、という事ができる
* Colaboratory の方が、他の人と共有・共同作業をしやすい

このような理由でで、Colaboratoryそっくりさんのイメージが必要と思い、作成しました。

実行方法
========

中身の前に、実行方法を説明しておきます。

#### 1. まず、nvidia-docker2 の環境をセットアップします。

* 参考： [Ubuntu16.04を入れて、nvidia-docker2を入れて、Chainerを動かす](https://qiita.com/ikeyasu/items/6e1069be9304f8342074)

#### 2. 以下の通り実行してDockerインスタンスを起動

```
$ docker run --runtime=nvidia -it --rm -p 8081:8081 --cap-add SYS_ADMIN --device /dev/fuse \
             --security-opt apparmor=unconfined ikeyasu/colab-local:latest
```

※ `--cap-add SYS_ADMIN`、`--device /dev/fuse`、`--security-opt apparmor=unconfined` は、Googleドライブをマウントするために必要です。([参考](https://funmatu.wordpress.com/2017/11/30/colaboratory%E3%81%A7%E7%B0%A1%E5%8D%98%E4%BE%BF%E5%88%A9%E3%81%AB%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E3%82%84%E3%82%8A%E5%8F%96%E3%82%8A%E3%82%92%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/))
※ ポートを変える場合、`-p 8081:8081` を変更してください。8082 に変える場合、 `-p 8082:8081` とします。

#### 3. ローカルランタイムに接続

1. Colaboratoryの右上の接続の右にある▼をクリックし、ローカルランタイムに接続をクリック
2. バックエンドポートをDocker起動時に指定したポート番号をしていして、接続をクリック

#### ※Jupyter Notebook を動かすホストが、localhost ではない場合

Colaboratory が接続するホストは、localhsot に固定されているので、別のPCでJupyter Notebookを動かしている場合、
SSHでポートフォワードをする必要が有ります。

Mac や Linux の場合は以下のようにしてください。

```
$ ssh user@example.com -L 8081:localhost:8081
```

Windowsの場合は、PuTTY等を使ってポートフォワードしてください。[参考](https://qiita.com/saba1024/items/5cf626dbf0c0896e9b49)


Dockerイメージの中身の概要
===================

* Dockerfile : https://github.com/ikeyasu/docker-colab-local
   * [これ](https://github.com/googlecolab/backend-container/blob/master/containers/)を元にしている
* OSは、Colaboratoryと同じUbuntu17.10
    * 但し、nvidia-docker2 用のイメージにしている（CuDNN等が入っている）
* インストール済みのPythonライブラリは全てColaboratoryと同じ（はず）
* Colaboratory と同じく、Tensorflowをインストール済み

ColaboratoryそっくりさんのDockerイメージの作成の記録
=====================================

Dockerfileは以下で公開しています。

https://github.com/ikeyasu/docker-colab-local

そもそも、オリジナルのColaboratoryのイメージらしきものが、以下で公開されています。

https://github.com/googlecolab/backend-container/blob/master/containers/

ですが、以下の点で、そのままは使えません。

* Google Cloud Container Builder でビルドする前提になっている
* Jupyter Notebookではなく、datalab というアプリを起動している（それが何なのかは未調査）
* nvidia-docker2 前提のイメージではない

なので、色々と変更しました。

* datalab のアプリ関連のインストール削除
* Jupyer Notebook を起動するようにする (tini を利用)
* ホームディレクトリの変更
* [jupyter_http_over_ws をインストール](https://research.google.com/colaboratory/local-runtimes.html)

また、NVIDIA が公開している Docker イメージが、Ubuntu 16.04、17.04 しか無いため、Colaboratory がベースにしている、Ubuntu 17.10 のイメージがありません。
そのため、以下を変更したイメージを作成しました。

Docker Hub: https://hub.docker.com/r/ikeyasu/cuda/
Dockerfile: https://github.com/ikeyasu/docker-cuda

ベースとするイメージをUbuntu 17.10に変えた以外に、LD_LIBRARY_PATHを追加しています。