云主机上快速搭建 Jupyter Notebook 服务

Jupyter Notebook 是机器学习和数据分析领域经常会使用的的 Web IDE 工具,本地使用非常方便。那么,如果你想在自己的云主机 AWS, GCP 等上搭建 Jupyter Notebook,并支持远程访问,该如何做呢?

首先,非常建议大家在 AWS, GCP 等境外云主机上搭建,相比于国内阿里云等有两个非常明显的优势:

  • 外网在安装各种模块和组件时非常方便,不用另外配置 Proxy。
  • 外网机器支持绑定未备案域名。

安装 Docker 容器服务

搭建 Jupyter Notebook 最便捷的方式是基于 Docker 容器服务,方便管理,不会污染主机环境且支持多人开启多个镜像同时使用。

当然,JupyterHub 本身就是一个支持多人使用的 Jupyter Notebook 环境,但是本文不会使用 JupyterHub。

Docker 容器服务可以非常方便地通过 Docker 官网给出的步骤完成,没有任何难度。

获取 Jupyter Notebook 镜像

Jupyter 官方给出了数个不同用途的镜像,都位于:https://github.com/jupyter/docker-stacks 开源仓库中。

这些镜像均提供了 Docker Hub 地址,只需要通过 docker pull 即可方便拉取。例如,如果你经常做数据分析,那么推荐拉取:

$ docker pull jupyter/datascience-notebook

上面的进行提供了 Python 和 R 语言的 Kernel,按预先安装好了常用的模块及 Anaconda 环境。不过,该镜像大小超过 2 GB,如果你用不到可以拉取基础镜像:

$ docker pull jupyter/base-notebook

安装 Let’s Encrypt 支持 HTTPS 访问

如果你想通过域名或 IP 远程访问 Jupyter Notebook 服务,那么非常推荐安装 SSL 证书支持 HTTPS 访问。这里使用 Let’s Encrypt 提供的免费证书。

你可以通过 Certbot 非常方便快捷地为域名生成 Let’s Encrypt 提供的免费证书。选择你使用的服务和系统:

服务选择 None of the above 即可,以 Ubuntu 16.04 为例,安装 Certbot 组件:

$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install certbot

使用 sudo certbot certonly 生成证书,按照提示一步一步完成即可。注意,生成证书时要保证 80 端口没有被占用。一般情况下,生成好的证书会在 /etc/letsencrypt/live/ 路径的下方。

注意,Let’s Encrypt 提供的免费证书默认有效期为 30 天,所以到期后需要通过 $ sudo certbot renew 来更新证书。

启动 Docker 容器服务

一切准备就绪,现在就可以启动 Docker 容器服务了。非常推荐写一个类似于 run-noteboot.sh 的 Bash 脚本,方便重复使用。

启动 Jupyter Notebook 容器服务的命令如下。我们以 notebook.example.com 域名为例:

docker run -d -p 443:8888 --name="jupyter-notebook-ssl" \
	--user root -e GRANT_SUDO=yes -e JUPYTER_ENABLE_LAB=yes \
	-v /etc/letsencrypt/live/notebook.example.com:/etc/ssl/notebook \
	jupyter/base-notebook start-notebook.sh \
	--NotebookApp.password='sha1:67c9e60bb8b6:9ffede0825894254b2e042ea597d771089e11aed' \
	--NotebookApp.certfile=/etc/ssl/notebook/fullchain.pem \
	--NotebookApp.keyfile=/etc/ssl/notebook/privkey.pem

其中:

  • -p 443:8888 :把 Jupyter Notebook 默认的 8888 端口指向 443 端口,以便通过 HTTPS 访问。
  • --name="jupyter-notebook-ssl" :启动后容器名字指定为 jupyter-notebook-ssl ,也可以不设置。
  • --user root -e GRANT_SUDO=yes:设置用户权限,方便在 Jupyter Notebook 使用 sudo 命令。
  • -e JUPYTER_ENABLE_LAB=yes:默认以 Jupyter Lab 新界面启动。
  • -v /etc/letsencrypt/live/notebook.example.com:/etc/ssl/notebook:将主机上生成的证书复制到容器中,否则容器会因为找不到证书而无法正常启动。/etc/letsencrypt/live/notebook.example.com 路径需要根据主机证书放置位置设定,: 后面路径可以不做更改。

接下来,就是启动镜像名称(jupyter/base-notebook)及设置其他参数,其中:

  • —NotebookApp.password= 为 Jupyter Notebook 环境设置登录密码,参数值可以通过下方的命令生成:
In [1]: from notebook.auth import passwd
In [2]: passwd()
Enter password:
Verify password:
Out[2]: 'sha1:67c9e60bb8b6:9ffede0825894254b2e042ea597d771089e11aed'

最后的两个参数是容器中的证书路径,即上面从主机复制证书到容器中时的 /etc/ssl/notebook 路径。你可以自行修改,但要保证路径一致,否则容器将无法正常启动。

如果你将上面的启动命令写入了 run-noteboot.sh 脚本中,只需要运行即可:

$ sh run-noteboot.sh

如果你已经正确设置了域名解析,现在就可以通过 https://notebook.example.com 来访问你的线上 Jupyter Notebook 环境了。

错误排除

如果不能正常访问,一般是容器没有正常启动造成的。首先,通过 $ docker ps,查看正在运行容器的列表。如果没有 jupyter-notebook-ssl,即代表容器未运行。此时,可以通过 $ docker logs jupyter-notebook-ssl 来查看容器终止运行的日志,进一步排查错误。

搭建环境的小坑还是比较多,如果遇到报错无法解决,可以通过搜索引擎获得合适的解答。