昔我往矣

Jupyter Notebook服务搭建过程

2019年12月13日

每次使用Jupyter Notebook都是在本地终端运行jupyter-notebook启动的,家里的树莓派上面已经运行了seafile, transmission-daemon,minidlna.service等服务,这次想着把Jupyter Notebook也搭建到树莓派上,提供在线编程能力。下面是搭建的过程。

1_m87_Htb_9Pstq0UcvNJ49w.png

安装

安装比较简单,我用的树莓派3B+,Raspbian GNU/Linux 10 \n \l系统上已经自带了Python3.7,我个人也比较倾向使用Python的这个版本。安装过程如下:

sudo python3.7 -m pip install jupyter

安装完成之后,可以启动验证下试试看。

$ jupyter-notebook 
[I 22:25:20.137 NotebookApp] Serving notebooks from local directory: /home/pi
[I 22:25:20.137 NotebookApp] The Jupyter Notebook is running at:
[I 22:25:20.138 NotebookApp] http://localhost:8888/?token=ceac4aa56f0f093ff662b6efc8043885efe9e8991ed84549
[I 22:25:20.138 NotebookApp]  or http://127.0.0.1:8888/?token=ceac4aa56f0f093ff662b6efc8043885efe9e8991ed84549
[I 22:25:20.138 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[W 22:25:20.161 NotebookApp] No web browser found: could not locate runnable browser.
[C 22:25:20.162 NotebookApp] 
    
    To access the notebook, open this file in a browser:
        file:///home/pi/.local/share/jupyter/runtime/nbserver-11849-open.html
    Or copy and paste one of these URLs:
        http://localhost:8888/?token=ceac4aa56f0f093ff662b6efc8043885efe9e8991ed84549
     or http://127.0.0.1:8888/?token=ceac4aa56f0f093ff662b6efc8043885efe9e8991ed84549

其中有一行是 No web browser found: could not locate runnable browser.,如果在桌面系统运行,Jupyter Notebook会自动打开浏览器,进入Jupyter Notebook的界面,树莓派的ssh远程字符界面无法调起浏览器,所以出现了这个报错,不是什么问题。看到上面的输出就代表jupyter已经安装好了。

配置

下面进入配置过程,Jupyter Notebook 默认使用tokan认证,也就是上面输出的 http://127.0.0.1:8888/?token=ceac4aa56f0f093ff662b6efc8043885efe9e8991ed84549 url里的一长串随机token。我们更希望使用固定的密码来认证,而不是每次启动都换一个token。

首先,生成jupyter-notebook的配置文件。

$ jupyter-notebook  --generate-config
Writing default config to: /home/pi/.jupyter/jupyter_notebook_config.py

等下再来编辑这个配置文件,先给jupyter-notebook生成登录密码,方法如下:

$ ipython
In [1]: from notebook.auth import passwd
In [2]: passwd()                                                                                                                                                                                       
Enter password: 
Verify password:
Out[2]: 'sha1:050xxxfe9:f7e9b392fb92xxxx86a0e8959a46578c'

最后一行输出的就是密码。解读下这串密码:sha1:050xxxfe9:f7e9b392fb92xxxx86a0e8959a46578c 字符串以冒号:分割,第一段是密码加密算法sha1,第二个字段是生成密码使用的盐(salt),最后一段是加盐后的密码hash。为了保密,上面的密码传是我手动修改过的。

最后,我们来编辑之前生成的配置文件,编辑之后的内容如下(我们只看修改了的配置行):

$ mkdir /home/pi/jupyter_notebooks  # 预先创建保存notebook的目录
$ grep -Ev "^#|^$" ~/.jupyter/jupyter_notebook_config.py 
c.NotebookApp.base_url = '/notebook/'   # 指定url前缀,方便后面nginx做路前缀匹配
c.NotebookApp.ip = '0.0.0.0'            # 指定监听端口,默认是 127.0.0.1
c.NotebookApp.notebook_dir = '/home/pi/jupyter_notebooks'   # 指定notebook存放的路径,请预先创建好
c.NotebookApp.open_browser = False       # 启动的时候,不用打开浏览器
c.NotebookApp.password = 'sha1:050xxxfe9:f7e9b392fb92xxxx86a0e8959a46578c'  # 加密后的密码
c.NotebookApp.port = 8888    # 监听的端口

此时再启动下,使用 jupyter-notebook 或者 jupyter-notebook jupyter-notebook --config=~/.jupyter/jupyter_notebook_config.py命令即可。效果如下:

$ jupyter-notebook --config=~/.jupyter/jupyter_notebook_config.py
[I 22:41:07.472 NotebookApp] Serving notebooks from local directory: /home/pi/jupyter_notebooks
[I 22:41:07.472 NotebookApp] The Jupyter Notebook is running at:
[I 22:41:07.473 NotebookApp] http://0.0.0.0:8888/notebook/
[I 22:41:07.473 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).

把Jupyter Notebook做成系统服务

编写systemd的文件

$ cat  /etc/systemd/system/jupyter-notebook.service 
[Unit]
Description=Jupyter-notebook Service
After=network.target

[Service]
User=pi
TimeoutSec=15
KillMode=process
ExecStart=/usr/local/bin/jupyter-notebook --config=/home/pi/.jupyter/jupyter_notebook_config.py

[Install]
WantedBy=multi-user.target

最后,重载systemd配置,并且启动jupyter-notebook.service

$ sudo systemctl daemon-reload  # reload systemd
$ sudo systemctl start jupyter-notebook.service 
$ journalctl  -u jupyter-notebook.service  # 查看Jupyter Notebook的启动日志
Dec 13 22:44:29 pi-99-2 systemd[1]: Started Jupyter-notebook Server.
Dec 13 22:44:32 pi-99-2 jupyter-notebook[12713]: [I 22:44:32.111 NotebookApp] Serving notebooks from local directory: /home/pi/jupyter_notebooks
Dec 13 22:44:32 pi-99-2 jupyter-notebook[12713]: [I 22:44:32.111 NotebookApp] The Jupyter Notebook is running at:
Dec 13 22:44:32 pi-99-2 jupyter-notebook[12713]: [I 22:44:32.111 NotebookApp] http://0.0.0.0:8888/notebook/
Dec 13 22:44:32 pi-99-2 jupyter-notebook[12713]: [I 22:44:32.112 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).

$ sudo systemctl enable jupyter-notebook.service   # 设置服务开机启动

最后的最后,我还希望把这个服务通过nginx进行一次包装,使用域名对外提供访问。nginx的server块配置如下

server {
    server_name i.xnow.me;
    
    location /cgi-bin/luci {
        proxy_pass http://r.xnow.me;
    }
    location /luci-static {
        proxy_pass http://r.xnow.me;
    }

    location /aria2/ {
        root /opt/www/;
    }
    location /transmission/ {
         client_max_body_size  100m;
        proxy_pass http://192.168.99.2:9091;
    }
    location /minidlna/ {
        proxy_pass http://192.168.99.2:8200/;
    }

    location /notebook {
        proxy_pass http://localhost:8888;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Origin "";
    }    
}

前面几个 location是我的其他服务的路径,后面一个 location /notebook {...} 是Jupyter Notebook相关的配置。因为Jupyter Notebook里用到了websocket,所以location块里面的配置proxy_set_header配置都是不可缺少的。

此时,无论是PC,Pad,手机还是其他设备,通过访问: http://i.xnow.me/notebook 就可以访问到树莓派上的Jupyter Notebook了。

当前暂无评论 »

添加新评论 »