JupyterNotebookを使う

私の3通りのRの使い方

WindowsのRGui

良いところ

グラフ(画像)がその場で表示される。

悪いところ

ヘルプがブラウザーで表示される(見るたびにタブが増えていく)。Linuxで解析したデータを読み込むのが面倒(SCPとかウェブ経由でダウンロードとか)。

LinuxにSSHで接続してR

良いところ

スクリプトを自動実行できる(Rscript)。作業ディレクトリで起動する。データベース(PostgreSQL)と連携しやすい。

悪いところ

図を表示できない。

LinuxでJupyterNotebookを起動し、Windowsからブラウザー経由で使う

良いところ

コード(解析手順)と図と説明・考察を一つのファイルにまとめることができる。

悪いところ

環境構築が面倒。

Dockerを使ってJupyterNotebookを起動する

JupyterNotebookをインストールしようとすると、pythonとか、anacondaとか、pipとかが必要になり、それらのバージョンをそろえたりと、単に手間がかかるだけでなく、現存の環境と不整合を起こしたりします。
そこでDockerを利用します。JupyterNotebookを動かすための環境が整ったイメージを使えば、他のソフトとの競合も発生することなく利用できます。

Dockerイメージを探す

# docker search jupyter
INDEX       NAME                                           DESCRIPTION                                     STARS
docker.io   docker.io/jupyter/datascience-notebook         Data Science Jupyter Notebook Python Stack...   980
(以下省略)

一番上の docker.io/jupyter/datascience-notebook を使ってみる。

Dockerイメージのダウンロード

# docker pull docker.io/jupyter/datascience-notebook

Dockerコンテナの起動

イメージをテンプレートにして実際にプログラムを実行する環境をつくる。

# docker run -d --name mynote docker.io/jupyter/datascience-notebook
# docker logs mynote
(途中省略)
[C 06:22:30.186 NotebookApp]
    To access the notebook, open this file in a browser:
        file:///home/jovyan/.local/share/jupyter/runtime/nbserver-8-open.html
    Or copy and paste one of these URLs:
        http://edfb3dfc0f44:8888/?token=69989a8a1be58d22b013b6223f69cdb602344fe1ab4bb290
     or http://127.0.0.1:8888/?token=69989a8a1be58d22b013b6223f69cdb602344fe1ab4bb290

docker runに-dオプションをつけて、バックグラウンドで実行させる。–nameオプションでコンテナに名前をつける。
docker logs でJupyterのログを出力させ、接続に必要な情報(http://127….)を得る。

しかし、このままではjupyterに接続できない。jupyterが動いている(待ち受けている)ポートが8888であるが、これはdockerのコンテナが提供するポートで、外から接続できないためである。コンテナ内のポートに接続できるようにするためにはホストマシンのポートにつなぐ必要がある。
一旦コンテナを削除し、-pオプションをつけてコンテナを作り直す。

# docker stop mynote
# docker rm mynote
# docker run -d --name mynote -p 10080:8888 docker.io/jupyter/datascience-notebook
# docker logs mynote
(途中省略)
     or http://127.0.0.1:8888/?token=901472142b49b5a072a3b66e3320c6bf47ad199c11687b64

jupyterの起動確認のためにcurlで接続してみる。

$ curl -D - "http://127.0.0.1:10080/?token=901472142b49b5a072a3b66e3320c6bf47ad199c11687b64"
HTTP/1.1 302 Found
Server: TornadoServer/6.1
Content-Type: text/html; charset=UTF-8
Date: Mon, 27 Feb 2023 08:39:45 GMT
Location: /tree?token=901472142b49b5a072a3b66e3320c6bf47ad199c11687b64
Content-Length: 0

上記のように返ってこればjupyterは起動しているので、127.0.0.1をLinuxのIPアドレスに変更して外部から接続できるはず。もし接続できなければ、linuxのファイアウォールの設定を確認する。

JupyterNotebookの運用

トークンの削除

jupyterに接続するURLに含まれるtoken=の部分は、jupyterを起動するたびに変更される。もしjupyterが動作するサーバーに外部から接続できないのであれば、tokenを固定もしくは削除して動作させると楽です。
tokenの指定方法は3通りあり、(1) jupyter_notebook_config.pyに設定、(2) 環境変数として設定、(3) jupyterの起動時オプションとして設定、のいずれかでできます。

(1)の方法はコンテナを削除すると元に戻ってしまいます。すでにコンテナを修正していて、削除したくないときはこの方法をとります。

# docker exec -it mynote bash
(base) jovyan@d4788834f9a1:~$ vi .jupyter/jupyter_notebook_config.py
(c.NotebookApp.token = とある行を修正。先頭の#を外すのを忘れないように)
(base) jovyan@d4788834f9a1:~$ exit
# docker restart mynote

(2)の方法はdocker runの-eオプションを使います。

# docker run -d --name mynote -p 10080:8888 -e JUPYTER_TOKEN=secret_token docker.io/jupyter/datascience-notebook

(3)の方法はjupyterの起動コマンドに引数を与えます。datascience-notebookはstart-notebook.shを起動することになっていて、これにtokenを引数として与えることができます。

# docker run -d --name mynote -p 10080:8888 docker.io/jupyter/datascience-notebook start-notebook.sh --NotebookApp.token=''

(起動時に実行されるコマンドを調べるには docker inspect mynote とし、出力されるJSONからCmdの値を探します。)

Rのパッケージを追加したくなったら

コンテナのコンソールに接続します。たぶんroot権限が必要になるので-uでユーザーを指定します。

docker exec -it -u root mynote bash
(base) root@edfb3dfc0f44:~# R
> install.packages("BiocManager", repos = "https://cran.ism.ac.jp/")
(途中省略)
> q()
Save workspace image? [y/n/c]: n
(base) root@edfb3dfc0f44:~# exit

作成したコンテナを保存したくなったら

コンテナをexportします。

# docker export mynote >mynote.tar

戻すときはimportです。

作成したコンテナを他の場所でも使いたくなったら

コンテナをcommitします。

# docker commit mynote mynote_image

作成されたdockerイメージ(mynote_image)をsaveします。

# docker save mynote_image -i mynote_image

作成されたmynote_imageを使いたい場所へもっていって、loadします。

# docker load -i mynote_image