signed

QiShunwang

“诚信为本、客户至上”

从零开始的 Jupyter 云服务器完全搭建指南

2020/12/29 6:00:47   来源:

0. 前言

由于移动工作的需要,相比于把代码环境放在本地我一直更倾向于将其放在云端。毕竟即使用手机和 iPad 也能随时使用和电脑相同的开发体验这实在是太棒了不是吗。因此这段时间为了写作业和做一点自己的小项目,我决定用云服务器搭建一个随时可用的在线 Jupyter 环境,用来写 Python 和 Julia 。

由于网上各类教程里五花八门的错误,中间也走了一些弯路,因此在这里记录一下,也分享给需要的其他朋友。

本篇文章主要包括的部分有:

  • 搭建环境的前期准备

  • Jupyter 环境的简单安装

  • 给 Jupyter 服务器正确配置 https 和域名

  • 安装 IJulia 环境

  • 连接 Jupyter 服务器

其中尤其是第三步的部分,网上几乎就没有正确的教程。而裸露 IP 并开放防火墙的 Jupyter 不仅不安全,还容易导致各种其它问题,因此非常不推荐。

1. 搭建环境的前期准备

那么既然要搭建一台云服务器并配置域名,当然需要

  • 一台云服务器(教程使用 Ubuntu 20.04 系统)

  • 一个已经实名并备案过的域名

  • 域名的 SSL 证书

  • 一个好用的 ssh 应用,个人推荐 Termius ,全平台同步 ssh

如果不会使用 ssh 工具的话,也可以直接在云服务器的管理界面点击登录就可以进入 Shell 了。

2. 安装 Conda 并更换国内源

一般来说各大服务商的云服务器 Ubuntu 镜像都已经内置更换好了 apt 源,就如我选择的是腾讯云 CVM,那么里面的 apt 走的就是腾讯源;因此一般并不需要将 apt 源更换到国内源。如果有需要的朋友可以将其更换至清华源,上面已经有完整的教程,这里不再赘述。不过在安装前理应先升级一下:

$ su  # 切换到 root 用户
$ apt update && apt upgrade

2.1 安装 Miniconda

Conda 是一个用于科学计算的 Python 发行版,我们选择从清华源来下载 Conda 。相比于各大傻瓜教程里给的 Anaconda ,我更喜欢 Miniconda 。不臃肿,需要什么包就自己装,这对云服务器非常友好。

从这一步开始不推荐使用 root 用户来进行操作。不要像有些教程里那样将 Jupyter 安在 root 下,还在设置里开放权限!如果你用的是 Ubuntu 20.04 镜像的话很可能你一进来的默认用户名是 ubuntu,用这个会安全很多。

首先我们访问清华 tuna 镜像站 Miniconda-release,找到最新的 miniconda 包,譬如我这里最新的就是 Miniconda3-py39_4.9.2 。右键复制一下其下载链接,然后在 Bash 里面:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7mCuzilf-1609187496536)(https://secure-static.wolai.com/static/9Cjsrjb7QjUHWgNUKy8hnR/image.png)]

$ wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-py39_4.9.2-Linux-x86_64.sh
$ bash Miniconda3-py39_4.9.2-Linux-x86_64.sh
$ source ~/.bashrc

即可完成 Conda 的安装。此时你应该看到你的 Bash 里的 $ 前面多了一个 (base) 。这个就是你的 Conda 默认环境。输入 conda —-v 来查看你的版本,效果如下。

(base) ubuntu@VM-0-8-ubuntu:~$ conda --v
conda 4.9.2

2.2 切换 Conda 源为清华源

由于国外源的下载速度过慢,我们将 Conda 的源切换到清华 Tuna 镜像站。首先我们来修改用户目录下的 .condarc 文件:

$ vim ~/.condarc

如果你的系统镜像丧心病狂地没有集成 vim 那么请自行安装一下或者使用 vi 将就。如果连 vi 都没有请使用 nano 。如果连 nano 都没有还不会安装请上门把服务商的公司砸烂。打开后按 i 进入 Insert 模式,向内输入:

channels:
  - defaults
show_channel_urls: true
channel_alias: https://mirrors.tuna.tsinghua.edu.cn/anaconda
default_channels:
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/pro
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2
custom_channels:
  conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud

之后按下 esc 退出 Insert,并输入 :wq! 来退出并保存编辑。之后运行 conda clean -i 清除索引缓存,保证用的是镜像站提供的索引。

3. 安装 Jupyter Notebook 并调整设置

3.1 安装 Jupyter

看起来很酷炫的 Jupyter Lab 经常出 Bug,因此我们还是选择安装较为基础而成熟的 Jupyter Notebook 。

(base)$ conda install jupyter notebook

这样就安好了。

3.2 配置前的准备

我们先为 Jupyter 准备一个密码。

(base)$ python
>>> from notebook.auth import passwd
>>> passwd() # 这一步之后输入你自己的密码并重复输入一次。会输出一长串加密后的东西,将其复制下来备用。
>>> quit() # 退出 Python 环境 

将生成的这一段单引号里的东西复制下来备用。新版本一般是用的 Argon 算法加密。

之后将你准备好的域名的 SSL 证书下载下来(一个 pem 格式的证书文件和一个 key 格式的文件),并上传到服务器的 ~/.jupyter 文件夹里备用。如果你的服务商只提供了 crt 形式的证书,那就:

$ openssl x509 -in xxx.crt -out xxx.pem -outform PE

3.3 设置 Jupyter 配置文件

我们给 Jupyter 创建一个设置文件,并打开

(base)$ jupyter notebook --generate-config
(base)$ cd ~/.jupyter # 进入 jupyter 配置目录
(base)$ vim jupyter_notebook_config.py # 打开配置文件 

之后你会看到打开了一个全都是注释的文件,如下图所示:

在这里我们需要找到几行,将注释号 # 去掉并修改,当然你可以直接 cmd + F 进行搜索。不推荐直接在文件后面直接添加本段代码。

c.NotebookApp.allow_origin = '*'
c.NotebookApp.allow_remote_access = True
c.NotebookApp.certfile = '/home/ubuntu/.jupyter/xxx.pem' # 这里是 pem 证书文件的路径
c.NotebookApp.ip = '127.0.0.1' # 除非 IP 裸连否则不要改成 '*'
c.NotebookApp.keyfile = '/home/ubuntu/.jupyter/xxx.key' # 这里是 key 文件的路径
c.NotebookApp.notebook_dir = '/home/ubuntu/iPython' # 这里是你想让 Jupyter 放项目的文件夹
c.NotebookApp.password = 'xxxxxx' # 这里放你刚刚设置密码的时候生成的那一长串东西
c.NotebookApp.open_browser = False # 服务器没有浏览器 开什么开
c.NotebookApp.port = 8888 # 这里是 Jupyter 的端口,自己选个就行,反正后面要做端口转发

改完之后同样退出并保存。这个时候运行

(base)$ jupyter notebook

就可以启动 Jupyter 了,如果你选择 IP 裸连的话,在云服务器安全组里开放一下你选择的端口,并输入 IP:8888 就可以进入连接。

3.4 Jupyter 插件的安装

Jupyter 也可以安装各种插件。最简单的方式就是

(base)$ conda install -c conda-forge jupyter_contrib_nbextensions

剩下的在打开页面之后有 GUI,这里就不讲了。

4. 给 Jupyter 配置域名访问

这一部分是我最火大的部分。网上的各种教程几乎全是错的。按照他们的配置好 nginx 之后确实可以访问 Jupyter 主页,但创建笔记本后无法连接到 kernel,也就是根本无法使用 Python 和 Julia。我甚至怀疑他们是不是配完干脆就再也没用过 Jupyter。下面给出我自己的正确配置方式。

注意要首先切换到 root 用户。

$ su # 切换到 root
$ sudo apt-get install nginx
$ source ~/.bashrc
$ cd /etc/nginx # 进入nginx 配置文件夹
$ ls # 显示文件夹内所有文件 

应该显示下面的结果:

当然里面本来是不应该有 jupyter.conf 的。那么我们先打开配置文件 nginx.conf :

$ vim nginx.conf

并在里面 http 打头的括号里添上一句 include /etc/nginx/jupyter.conf; ,如图所示。

之所以这么做是因为众所周知把不同的东西封装起来放在不同文件里是好习惯。之后我们保存并退出编辑后,在 nginx 的配置文件夹里新建一个 jupyter.conf 并打开:

$ vim jupyter.conf

将下面这段内容改好之后输进去:

server {
        # 将服务转发到 443 端口,通过 https 访问
        listen       443 ssl;
        
        # 这里填写你的域名和 IP
        server_name  xxx.com  ip.ip.ip.ip;
        
        # ssl 配置,填写你的 pem 和 key 路径
        ssl on;
        ssl_certificate      /home/ubuntu/.jupyter/xxx.pem;
        ssl_certificate_key  /home/ubuntu/.jupyter/xxx.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        # 下面这段是 Websocket 配置
        location / {
              # 注意这里 8888 改成你自己用的端口,更注意这里放 https 而不是 http
              proxy_pass https://127.0.0.1:8888;
              index  dashboard index;

              #websocket额外配置开始
              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection "upgrade";
              # 连接超时时间,不能设置太长会浪费连接资源
              proxy_connect_timeout 60s;
              # 读超时时间
              proxy_read_timeout 500s;
              # 写超时时间
              proxy_send_timeout 500s;
              #websocket额外配置结束

              proxy_set_header Host       $http_host;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Proto $scheme;
        }

        # 日志路径设置
        access_log  /home/ubuntu/.jupyter/jupyter.log;
        error_log   /home/ubuntu/.jupyter/error.log;
} 

我现在找到的所有的关于这部分配置的文章,不知道为什么都没有使用 Websocket 配置,导致打开后无法连接 kernel。直到我去翻阅了整篇 Jupyter Notebook 官网的手册,终于在一个角落发现了它用的是 Websocket 。

这个时候你已经完成了 Nginx 的配置,之后只需要启动 Jupyter 和 Nginx 就可以访问了:

(base) ubuntu$ nohup jupyter notebook --allow-root > jupyter.log 2>&1 & # 后台运行 Jupyter
(base) ubuntu$ su root
(base) root$ systemctl start nginx.service # 启动 Nginx 服务 

来,打开你的域名,输入密码,开始享受 Jupyter 带来的便利吧。

5. 安装 Julia

除了 Python,Julia 也是科学计算的好选择。那么当然要装一下。虽然 apt 里面有 Julia 可以安装,但并不推荐。

首先打开我们的老朋友清华 Tuna 开源镜像站 Julia-release,找到适合 x86 Linux 的最新版本,老规矩:

$ wget https://mirrors.tuna.tsinghua.edu.cn/julia-releases/bin/linux/x86/1.5/julia-1.5-latest-linux-i686.tar.gz
$ tar -xzvf julia-1.5-latest-linux-i686.tar.gz # 解压二进制文件
$ cd Julia-1.5.x # 取决于你下载的版本  

之后将你的 Julia 路径,也就是刚刚你 cd 的那个文件夹下 bin 文件夹的路径添加到环境变量里面:

$ cd # 进入你的用户文件夹
$ vim ~/.bashrc # 打开环境变量文件 

在里面添加两句:

export PATH=$PATH:/home/ubuntu/julia/bin # 添加环境变量
export JULIA_PKG_SERVER=https://mirrors.tuna.tsinghua.edu.cn/julia # 添加清华源为 Julia 包源

之后同样再

$ source ~/.bashrc # 刷新环境变量
$ julia # 启动 Julia 

进入 Julia 界面后,我们输入 versioninfo() 就可以查看当前的 Julia 版本、运行环境和所在的包源。如果你看到了 Tuna 的网址说明源设置正确了。

下一步就是安装 IJulia,和 IPython 是一样的东西,不过 Jupyter 就是基于 IPython的因此不必单独安装 IPython。

julia> using Pkg
julia> Pkg.add("IJulia") 
julia> exit() 

如果成功安装,那么大功告成。进入你的 Jupyter 页面,新建选项里除了 Python 3 就多了 Julia!

6. 在不同设备上连接 Jupyter

在 PC 或 Mac 上显然用浏览器就可以直接连接,但同样的 UI 并不适合移动端。

这里推荐一个 iOS 端的用于连接 Jupyter 的 App : Juno Connect。

颜值高,连接稳,如果有桌面端该有多好。

写在后面

教程大概就到此为止了。剩下的还有一些优化(比如 Jupyter 的 css 啊之类的)还是需要自己动手做,不过就不在本教程的范围内了。如果你发现这里有什么问题,欢迎与我交流。