Dropbox同期可能なJupyter Notebookリモート接続用Windowsサーバ構築

# はじめに
この記事では、私がJupyter Notebookにリモート接続するためのサーバを、Windows上に構築したときの手順を、記録として残します。なお、Jupyter NotebookのホームディレクトリにはDropboxを使い、データのクラウド共有も同時に実現する形にしてみました。

# Anacondaを用いたWindows上への環境構築
ここでは、AnacondaというPythonのパッケージを使って、Windows上にPythonの実行環境とJupyter Notebookのインストールを一気にやってしまいます。

### Anaconda3インストーラ入手
以下の公式サイトから、Windows用インストーラを入手できます。ここでは、Pythonのバージョン3系統に相当する、Anaconda3シリーズを導入します。
https://www.anaconda.com/download/
ところが、この公式サイトはダウンロードが途切れがちです。以下のミラーサイトからもインストーラがダウンロードできます。
https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/
使用するマシンが64bitの場合、ここから、Anaconda3のWindows-x86_64向け最新版をダウンロードしてきます（本記事執筆時点では[Anaconda3-5.0.1-Windows-x86_64.exe](https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-5.0.1-Windows-x86_64.exe)でした）。

### Anacondaインストール
インストーラの.exeファイルを入手したら、実行してインストールします。インストール時の選択は基本的にデフォルトのまま進めていって良さそうです。かなり重いので時間がかかりますが、気長に待ちます。

### Jupyter Notebookの動作確認
Anacondaのインストールが完了すると、

Windowsのスタートメニューのアプリ一覧 > Anaconda3 (64bit) フォルダ

に、Jupyter Notebookへのショートカットが作られていると思いますので、実行してみます。コマンドプロンプトが開き、続いてブラウザが開いてJupyter Notebookのtree画面（ファイルやフォルダの一覧）が表示されたら、インストールと動作確認は成功です。

# Jupyter Notebookへのリモート接続
次に、いま動作確認したJupyter Notebookをサーバとして、外部の別マシン（クライアント）からリモート接続して利用できるようにします。これによって、出先でもWebブラウザさえ使えればすぐにJupyter Notebookの恩恵にあずかれるようになります。

### 外部接続用パスワードの生成
まず、パスワードを設定します。これが無いと、誰でも自由にリモート接続できるようになってしまいます。

Windowsのスタートメニューのアプリ一覧 > Anaconda3 (64bit) フォルダ

にある「Anaconda Prompt」を実行します。Anaconda環境でのコマンドプロンプトが開きますので、次のようにコマンドを実行します。

```
> pip install ipython
```

すると、パスワード生成に使うIPythonというツールがインストールされます（おそらく、すでにインストールされているとは思います）。続いて、次のコマンドを実行します。

```
> ipython
```

IPythonが起動しますので、そのまま、次の2行を1行ずつ順に実行します。

```
In [1]: from IPython.lib import passwd
In [2]: passwd()
```

2行目を実行すると、パスワードの入力が求められるので、確認も含め2回入力します。すると、次のような感じの文字列が画面に表示されます。

```
Out [2]: 'sha1:xxxxxxxxxxxx:xxxxxxxx......'
```

これは、さきほど入力したパスワードを、見た目ではわからないような形（ハッシュ値）へと変換した文字列です。この文字列は、この次の設定の工程で使いますので、コピーなどをしておいてください。


### 設定ファイルの生成

引き続き、Anaconda Promptで次のようにコマンドを実行します。

```
> jupyter notebook --generate-config
```

すると、ホームディレクトリ（通常は`C:\Users\ユーザ名`）の直下にある`.jupyter`フォルダの中に、`jupyter_notebook_config.py`というファイル（以下、設定ファイルと呼びます）が生成されます。もし何か質問文が表示されたら、`y`と入力すれば先に進めると思います。


### 設定ファイルの編集

`jupyter_notebook_config.py`を、外部からのリモート接続を受け付けられる設定に書き換えてやります。具体的には、つぎのような書き換えを行います。

- 全てのIPアドレスからの接続を許可する設定に変更。

```
162行目あたり

#c.NotebookApp.ip = 'localhost'
　↓
c.NotebookApp.ip = '*'
```

- Jupyter Notebook起動時にサーバ側で自動的にブラウザを開かせない設定に変更（任意）。

```
208行目あたり

#c.NotebookApp.open_browser = True
　↓
c.NotebookApp.open_browser = False
```

- パスワードの設定。さっき生成したハッシュ値をコピペします。

```
217行目あたり

#c.NotebookApp.password = ''
　↓
c.NotebookApp.password = 'sha1:xxxxxxxxxxxx:xxxxxxxx......'
```

- 利用するポート番号を変更。動作に必須の書き換えではないですが、デフォルトだとセキュリティ的に弱いので、変えた方がいいとは思います。以下では、例としてポート番号を11451に設定しています。

```
228行目あたり

#c.NotebookApp.port = 8888
　↓
c.NotebookApp.port = 11451
```

設定ファイルの書き換えは以上です。

### 外部からの接続確認

ここまで設定できたら、外部から接続できるようになっているはずですので、WebブラウザからIPアドレスとポート番号でアクセスしてみます。
例えば、サーバのLAN側IPアドレスが192.168.0.192で、設定ファイルでポート番号を11451に指定していたすると、同じLAN内にある他マシンからは次のアドレスでアクセスできます。

```
http://192.168.0.192:11451/
```

Jupyter Notebookのtree画面（ファイルやフォルダの一覧）が表示されたら、接続成功です。
LANの外からのインターネット経由での接続も、グローバルIPアドレスを指定すれば可能です。その際は、設定ファイルに指定したポート番号とサーバマシンのLAN側IPアドレスとの紐付け（ポートマッピング、いわゆるポート解放）が必要です。

# Dropboxとの連携
データCSVファイルなども含めたJupyter Notebookの状態をシームレスに連携したい、という需要が自分にはありましたので、Jupyter Notebookのデフォルト作業フォルダ（起動時に最初に表示されるフォルダ）を、Dropbox同期フォルダにしてしまいます。データCSVファイルなどは、もちろんJupyter Notebookの機能でアップロードやダウンロードができますが、頻度や数が多くなると、これらを自動化してしまいたい欲が出てきたわけです。

ここでは、サーバマシンにすでにDropboxのクライアントソフトがインストールされている前提で進めてゆきます。また、理屈上は、Dropbox以外のクラウドストレージ（Googleドライブ、OneDrive、ownCloudなど）でも同様のことが可能です。

### Jupyter Notebookの作業フォルダの変更

ここまでの動作確認では、Jupyter Notebookにアクセスすると、最初にWindowsホームディレクトリのファイル・ディレクトリ一覧が表示されていたと思います。つまり、デフォルト作業フォルダが、Windowsホームディレクトリになっているわけですが、この作業フォルダを、Dropbox同期フォルダへと変更してみます。

サーバマシン側で、

Windowsのスタートメニューのアプリ一覧 > Anaconda3 (64bit) フォルダ > Jupyter Notebook

を右クリックし、

その他 > ファイルの場所を開く

を実行します。するとエクスプローラのウインドウが開くので、Jupyter Notebookのアイコン（ショートカット）を右クリックし、プロパティを選択します。
なお、元のショートカットファイルをいじるのに抵抗がある場合は、ショートカットを複製してから、以下の処理を行ってください。

プロパティ画面の「リンク先」を見ると、末尾に`%USERPROFILE%`という文字列を見つけられると思います。この部分を、新たに作業フォルダに指定したいパスに書き換えてやります。
例えば、Dropboxの同期フォルダのパスを`C:\Dropbox\JupyterHome`とした場合、プロパティのリンク先を次のように書き換えます。

```
C:\Users\ユーザ名\Anaconda3\python............-script.py %USERPROFILE%
　↓
C:\Users\ユーザ名\Anaconda3\python............-script.py C:\Dropbox\JupyterHome
```

OKをクリックして保存したら、ショートカットをダブルクリックしてJupyter Notebookを起動します。

### 外部接続での確認

サーバ側でJupyter Notebookを起動したら、外部マシンからWebブラウザで先程と同じアドレスにアクセスしてみます。最初に表示されるフォルダがDropboxのものになっていたら成功です。
これで、どのマシンからアクセスしても、常に同じ作業環境が保てますし、分析対象のファイルなどもJupyter Notebook側と自動的かつシームレスに連携できます。

# Jupyter Notebookの使い方

ここまでの処理が完了すれば、自宅の使い慣れたPCはもちろんのこと、研究室のPCでも、ネットカフェのPCからでさえ、自分のJupyter Notebook環境でPythonプログラミングがいつでもどこでも可能になります。例えば、GPUの載っているパワフルなマシン上でJupyter Notebookサーバを立てておけば、利用時間無制限の[Google Colaboratory](https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja)のごとくディープラーニングのコードなどを動かすことも可能になります。

Jupyter Notebookの具体的な使い方は、以下の書籍が大変よくまとまっていますので、おすすめです。私自身も、この書籍でJupyter Notebookの利便性に感動しましたし、これまでなんとなく使ってきたmatplotlibへの体系的な理解を深めることができました。ネット上にも情報はもちろんありますが、やはり、日本語で体系的に情報がまとまっているのはありがたいです。

[PythonユーザのためのJupyter[実践]入門 大型本 – 2017/9/9](http://amzn.to/2DpyHqY)


# 参考にさせていただいたサイト様

- [Jupyter/IPython Notebook Quick Start Guide](http://jupyter-notebook-beginner-guide.readthedocs.io/en/latest/index.html)
- [Any Anaconda installer mirrors available? - Can't download any files from the site](https://groups.google.com/a/continuum.io/forum/#!topic/anaconda/bE--AVEO5Bk)
- [jupyter notebook で外部からの接続を許可する](https://qiita.com/ciela/items/0e0392f600c92b93d7c6)
- [Jupyterを導入しよう -リモート編-](https://qiita.com/Miggy/items/5466a2c1e968602f3ebe)