jupyterのservice化で詰んでた話

今大学の研究的なもので,Raspberry piを使った自動走行ラジコンカーを製作している.

Twitterを見ている方ならわかると思うが,頭の工作精度が悪いためにボディの作成に手間取った.

それ以上に手間取ったのがRaspberry piの設定だった.春休み中に某社でインターン的なことをしている際は一人に一つRaspberry piが支給され,それでプログラムを組むなどしていた.

その会社の独自(といっても外部に公開しているけど)のGitbookでセットアップ方法などはあったけど,最初の設定は普通にできてバリバリコードを書いたり,ハードを作ったりしてた.

持つものを持っている会社だったので,とてもホワイトな職場で,将来はこんな会社で働きたいなとも思った.ここで書いた話をもっとしようとすると話が脱線すると思うので 会社の話は後々することにしようと思います.

本題

Raspberry piのJupyterの設定で四苦八苦していた.

今回の本題はこんな感じ,なんか色々とわからなくて意気消沈していたら,結局は初歩的なミスだったって話をしようと思います.

やりたかったこと

Raspberry pi上でJupyterを動かして手元のノートPCで
ブラウザ上からコードを書いて動かせるようにしたかった

実際に起きたこと

Gitbookのコードが間違っていた.
タイポ怖い
コピペ,ダメ絶対

簡単に言うとこんな感じ,プログラムに強いフレンズの友人がいなかったらタイポがあるってわからなかった怖さ. 一番悪いのはここら辺に気づけない僕の頭だと思いますが,一応Raspberry piでのJupyter の Service化について書こうと思います.

Raspberry piのJupyter Service化

要件としてはpythonが入っていること,pipがインストールされていることを前提に話をします.

pipが入っていなければ以下のコマンドでダウンロードを完了させてください.

$ sudo wget https://bootstrap.pypa.io/get-pip.py
$ sudo python ./get-pip.py

多分これでpipが入るはず.入らなかったらググって,どうぞって感じ, これはjupyterが入る前の話なんですが,最初から入ってくるpipのバージョンがおっそろしく古いことがあって.

jupyterがインストールできないことがしばしばあるようです.jupyterが入らないって時はここを疑った方がいいかもしれません.

pip自体のバージョン確認は python -m pip -Vで確認ができます.

pipが入っていることが確認できたらjupyterのインストールです.sudo pip install jupyterでインストールが可能です. ちなみに10分以上かかるのでトイレにでも行っておいた方がいいと思います.

matplotlibなどを使いたい時にはswapが必要になるので個別に設定.まずはswapを停止.

 $ sudo /etc/init.d/dphys-swapfile stop

swap領域が少なすぎるのでswap領域を上げてあげる.僕の使ってるRaspberry piは最初は100でした.

sudo vi /etc/dphys-swapfile

このファイルの中から CONF_SWAPSIZEの部分を探して,1024くらいに値を変更してあげるとちょうどよいくらい.

これであとはswapを起動するだけ,

sudo /etc/init.d/dphys-swapfile start

無事に起動したらあとはrebootするとひとまずはOK.

今度は固定のtokenを設定する.

jupyter notebook --generate-config
vim ~/.jupyter/jupyter_notebook_config.py

コンフィグファイルが作成されるのでそれを変更する.

コンフィグファイルを開いたら c.NotebookApp.tokenのコメントアウトを消し、任意のTokenを指定する。(今回はhatoと指定)

<例>

## Token used for authenticating first-time connections to the server.
#
#  When no password is enabled, the default is to generate a new, random token.
#
#  Setting to an empty string disables authentication altogether, which is NOT
#  RECOMMENDED.
c.NotebookApp.token = 'hato'

vimだと/で検索ができるので便利,Emacsを使う人はやっぱりサイコパス

と言うわけでここでとりあえずjupyterは起動するようになったはず.

jupyter-notebook --ip= --config=/home/pi/.jupyter/jupyter_notebook_config.py

これで起動する(ブラウザが立ち上がる)

ちなみに同一LAN上にいると,別のデバイスのウェブ上からアクセスできる.

http://192.168.xxx.xxx:8888/

これでいける(xxxはifconfigなどで調べたraspberry piのIPを入れる).

この後にパスワードを入力するように求められるがこの場合先ほど設定したものを入れれば動く. 僕の場合tokenの部分でhatoとしているのでhatoと入力すれば良い.

僕はここまではできた.しかしこの先のService化でつまづいた.

service化

やることとしてはSystemedにしてservice化を有効にする.

/etc/sysyemd/system以下に、jupyter.serviceを作成する。

jupyter.serviceのファイルの中身はこのようになる.

[Unit]
Description = Jupyter Notebook

[Service]
PIDFile=/var/run/jupyter.pid
ExecStart=/usr/local/bin/jupyter-notebook --ip= --config=/home/pi/.jupyter/jupyter_notebook_config.py
User=pi
Group=pi
Restart=always
RestartSec=10
WorkingDirectory=/home/pi/Documents
Type=simple

[Install]
WantendBy=multi-user.target

このあと,設定を確認するために systemctl list-unit-files --type=service | grep jupyterと打つ.すると jupyter.service invalidなどと帰ってくるはず.これが帰って来ればjupyterのservice化はひとまずOK. sudo systemctl enable jupyterを打ち,サービスを有効化する. けれど僕はここでエラーが起きた.

エラー文

エラー文はよく覚えていなかったが,言っていることが「さっき作ったjupyter.serviceのところの[Install]の部分でエラーがあるわ,multi-user.targetって何やねん」って感じ.とりあえずmulti-user.targetについて調べて色々やって見たがいまいち動いてくれない.これで3日溶かした.辛かった.もっと他の場所を見るべきだったのにここしか見ていなかった.

解決

3日たってもうまく動いてくれず,解決は困難だった.それ以外にもRaspberry piで固定IPをしようとしてみるもことごとくダメ(インターネットに繋がらなくなる,解決はOSを焼き直す以外にない).いきなりワイヤレスインターフェイスが吹っ飛ぶなどのエラーにも遭う.ちょっと精神がやばかった.他の研究室でバリバリやっている人と対比して自分の今の境遇にとてつもない劣等感を覚えた.物憂げな表情で学食にいた時に,フルスタックエンジニアの同期に会ったので今の状態を話して見たらjupyterの問題が一気に解決した.

間違っていたところ.

間違っていたのはmulti-user.targetではなかった.その前のWantendByの部分のタイポだった.そもそもここの部分が間違っているなんて思いもしなかった.本当はWantedByで,nが不要なだけだった.これで実行してみたら,普通に全部通ってちょっと放心状態になった.

まとめ

コピペ,ダメ絶対

ちなみに間違っていた部分は会社の方にslack経由で指摘した.このような被害を出さないためにも今回の記事を書いた.