使用 Nginx 反向代理将 Jupyter Lab 绑定到子域名

我在能连接到公网的服务器上开了一个 Jupyter Lab 服务,平时用来看数据和测试一些代码。

考虑到用 Nginx 来管理 Web 服务的 IP 白名单和 HTTPS 证书会比较方便,而且,如果将 Jupyter Lab 绑定到子域名上,URL 中可以省去一个端口号,看起来比较美观。因此,我决定采用 Nginx 反向代理的方式,将服务绑定到子域名上。途中遇到了一些坑,在此记录一下。

相关版本情况

服务器系统:Ubuntu 20.04 LTS

Jupyter Lab 版本:3.2.8

Python 版本:3.10.1

宝塔面板版本:免费版 7.8.0

Nginx 版本:1.20.1

Jupyter Lab 服务器配置

因为 Nginx 和 Jupyter Lab 在同一台服务器上,反向代理就是访问本机 localhost,所以并不用特意设置 ServerApp 的 ip 字段,保持默认即可。

需要设置的字段只有一个,就是 ServerAppallow_origin 字段,需要将其设置为 「协议名+待绑定域名」的格式(如图 1)。例如 https://aaa.bbb.com。值得注意的是,这里的协议名是必须指明的,如果用的是 https 协议访问,那不写协议名或者写成 http 都是不可以的,仍然会有跨域问题。

图 1 设置 ServerApp 的 allow_origin 字段

Nginx 反向代理配置

我服务器上用的是宝塔面板,一开始我以为直接添加反向代理,将请求转发到 localhost 上的对应端口即可(图 2)。

图 2 宝塔面板添加 Nginx 反向代理

结果发现添加完成后,一旦访问,Jupyter Lab 就在终端里一直报错,浏览器中也只能加载出 UI,完全打不开文件。

查询资料后发现,报错有两个原因:

  1. Jupyter Lab 传输数据用的是 Websocket,它需要 HTTP 1.1 长连接的支持,而 Nginx 的反向代理默认采用 HTTP 1.0
  2. Websocket 连接在请求中需要用 ConnectionUpgrade 两个请求头指明使用 Websocket 协议,而客户端请求中的这两个请求头在通过 Nginx 反向代理时会被过滤掉,并不会自动转发。因为根据 HTTP 协议规范,UpgradeConnection 属于hop-by-hop 请求头,Nginx 作为中间的代理,按照规范不能直接转发hop-by-hop header

因此,需要在 Nginx 的反向代理配置中,额外加入这 3 行设置(如图 3),将 HTTP 协议版本指定为 1.1,以及添加 ConnectionUpgrade 两个请求头。

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

图 3 Nginx 补充设置

参考文献

[1] 遗忘. WebSocket 协议之 NGINX 代理转发无法建立连接问题处理 [G/OL]. CSDN 博客, 2020(20200316)[2020-03-16]. https://blog.csdn.net/yiwangC/article/details/104898519

[2] encoderlee. 使用 Nginx 为 TCP/WebSocket 协议做反向代理和几个易踩的坑 [G/OL]. CSDN 博客, 2019(20190512)[2019-05-12]. https://blog.csdn.net/CharlesSimonyi/article/details/90122916

[3] 虎嗅蔷薇. nginx 代理 WebSocket 及 HTTP[G/OL]. 虎嗅蔷薇, 2021(20210510)[2021-05-10]. https://www.funkit.net/202105/fbc19c2049e7.html

[4] 永夜初晗凝碧天. 配置 Nginx 反向代理 WebSocket[G/OL]. 个人博客, 2020(20200113)[2020-01-13]. https://yongnights.github.io/2020/01/13/%E9%85%8D%E7%BD%AE%20Nginx%20%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%20WebSocket/

[5] Jinzhong Xu. 利用 nginx 反向代理为 jupyterlab 配置二级网址页面 [G/OL]. J Blog, 2020(20201109)[2020-11-09]. https://xujinzh.github.io/2020/11/09/jupyterlab-nginx/

发表评论

您的电子邮箱地址不会被公开。