ブログに書くほどではない小さな話題についてブラウザ上で気軽にメモを取れる環境を構築したいなと思っていました。欲しい条件としては
という感じでした。
以前見かけたバイオインフォマティクスで実験ノートを取ろうというプレゼンではDocBaseというサービスが紹介されていました。
試してみたのですが、
- 数式のレンダリングがリアルタイムでない(中の人によるとリアルタイムらしいのですが、それに気が付かない程度に遅い)
- 月額使用料が最低1000円とあまり手軽でない
- まだ実績のないサービスにドキュメントを保存するのは不安がある
という理由から積極的に使う気にはなれませんでした。
という話をTwitterに書いたらJupyterを使ったらよいのではないかという提案をいただきました。
JupyterはIPython NotebookがPython以外の言語にも対応するにあたってスピンオフしたプロジェクト(要出典)らしいです。
使ってみたらいい感じだったのでインストール方法をメモしておきます。
インストール
サーバー上にWebサービスを立ててブラウザからアクセスして使う方法を説明します。
公式ドキュメントを読みました。
pipなどの適当な環境が整っていれば
pip install jupyter
だけで完了です。
SSHポートフォワードの設定
ssh user@example.com -L 8888:localhost:8888
を実行すると、localhostの8888にSSH先のサーバーから見たlocalhost(つまりSSH先のサーバー自身)の8888がマップされた状態でSSH接続できます。
その状態で
jupyter notebook
を実行するとURLが表示されます。
ローカルでそのURLにアクセスするとサーバー上のjupyter notebookに接続できます。
バックグラウンドで実行したい場合は、サーバー上で
nohup jupyter notebook > /dev/null 2>&1 &
でjupyter notebookを立ち上げてログアウトし、ローカルで
ssh -f user@example.com -L 8888:localhost:8888 -N
とすればよいです。(-fはバックグラウンド実行のオプション、-Nはリモートで何もしないオプション)
踏み台サーバーがある場合には~/.ssh/configに
Host fumidai Hostname fumidai.example.com User hoge ForwardAgent yes Host main Hostname main.example.com User hoge ProxyCommand ssh -W %h:%p fumidai
と書いたうえで
ssh -f main -L 8888:localhost:8888 -N
とすればいいはずです。
サーバーで動かす
SSHによる方法を知らなかった時の記述です。
あまりいい方法ではないですが、残しておきます。
これも公式ドキュメントを見ました。
まずはパスワードを設定します。
jupyter notebook --generate-config python > from notebook.auth import passwd > passwd()
として出てくるパスワード入力プロンプトに適当にパスワードを入力すると
'sha1:67c9e60bb8b6:9ffede0825894254b2e042ea597d771089e11aed'
のように暗号化されます。
~/.jupyter/jupyter_notebook_config.pyを開き、c.NotebookApp.password〜と書いてある行のコメントアウトを解除して、
c.NotebookApp.password = u'sha1:67c9e60bb8b6:9ffede0825894254b2e042ea597d771089e11aed'
のようにコピペします。
次にパスワードを平文で送らないようにするためにhttpsにする設定を行います。
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -sha256 -keyout mykey.key -out mycert.pem jupyter notebook --certfile=mycert.pem --keyfile mykey.key
のようにして証明書を設定します。
ドキュメントの通りのコマンドでやるとサポートされていない種類の証明書が出てくるようなので鍵の種類を変更しましたがこれでも古いらしいので気になる方は正しい設定を調べてください。また、この証明書だと誰にも認証されていないのでChromeなどでアクセスしたときに警告画面が出てしまいます。最近はやりのLet's Encryptとかを使えば解決しそうですがそんなに頑張ることでもないので無視します。
※追記
Let's Encryptで得た証明書を使えば警告なくアクセスできるようになりました。
git clone https://github.com/letsencrypt/letsencrypt cd letsencrypt ./letsencrypt-auto --help ./letsencrypt-auto --apache -d your.domain
ここではまったのは、一度Apacheなどの80番ポートをlistenしているプロセスを止めないといけないことと、ファイアウォール設定を変えて443番ポートにアクセスできるようにしないといけないということです。
鍵や証明書は/etc/letsencrypt/archive/ドメイン名/に置かれていますが、rootでないとアクセスできないので一般ユーザ権限で動かすJupyter notebookからはアクセスできませんでした。よい解決策が思い浮かばなかったので無理やりホームディレクトリにコピーすることでアクセスできるようにしましたが、セキュアな解決策ではないのでよろしくないです。
~/.jupyter/jupyter_notebook_config.pyを開き、各設定のコメントアウトを解除しながら次のように設定していきます。
c.NotebookApp.certfile = u'/absolute/path/to/your/certificate/mycert.pem' c.NotebookApp.keyfile = u'/absolute/path/to/your/certificate/mykey.key' c.NotebookApp.ip = '*' c.NotebookApp.password = u'sha1:bcd259ccf...<your hashed password here>' c.NotebookApp.open_browser = False c.NotebookApp.port = 8888
ここまで設定できたら
jupyter notebook
で起動して、ブラウザでhttps://自分のサイト:8888/にアクセスすれば動かせるようになります。
スクリーンショット
アクセスすると(証明書の警告画面の後で)パスワード入力画面になるので、パスワードを入力して入ります。
NewからNotebooksを選びます。"Kernel"を追加するとPython以外も選べるようになるらしいです。(IPython kernels for other languages · ipython/ipython Wiki · GitHub)
Markdownしか書かない時にPythonを選ぶのもおかしいのでいい感じのkernelを追加したいのですが、どれがいいのかよく分かっていません。
IPython Notebookと変わらないのでPythonのコードを入力してCtrl+Enterで実行できます。
Markdownモードに変更して
LaTeX記法で数式を打つと
数式として表示されます。
少し試した感触だと欲しい機能を満たしているのですが、Cellの移動など単なるメモはを取るには大げさなインターフェースなのでもっと手軽なのがあったら乗り換える可能性は残っています。書いたものをそのまま公開できる設定とかがあればもっと便利かもしれません(あるいはもうある?)
Web関係の知識がほとんどないのでこの冬休みに何か習得したいなぁと思っていますが、うまくいくのでしょうか。
追記
Atomにリアルタイムで数式のプレビューもできるプラグインがあるらしくとても良かったです。
AtomでMarkdown+数式を利用する - Qiita
が参考になります。
ローカルでAtomに書いて、Jupyterに貼るという運用がいいかも?