前言

Jupyter Notebook是一个强大的交互式计算环境,广泛用于数据分析、机器学习和教育领域。本文将详细介绍如何使用Nginx配置Jupyter Notebook的子路径访问,使您能够在同一域名下通过子路径访问Jupyter服务。

Jupyter配置

1. 生成配置文件

首先,生成Jupyter配置文件:

1
jupyter notebook --generate-config

这将在~/.jupyter/目录下生成jupyter_notebook_config.py文件。

2. 编辑配置文件

编辑~/.jupyter/jupyter_notebook_config.py文件,添加以下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 设置端口
c.NotebookApp.port = 8878

# 设置基础URL路径
c.NotebookApp.base_url = '/groot'

# 禁用密码和token(仅用于开发环境)
c.NotebookApp.password_required = False
c.NotebookApp.token = ''
c.NotebookApp.password = ''

# 允许远程访问
c.NotebookApp.ip = '0.0.0.0'

# 禁止自动打开浏览器
c.NotebookApp.open_browser = False

# 设置工作目录
c.NotebookApp.notebook_dir = '/path/to/notebooks'

Nginx配置

1. 基本配置

编辑Nginx配置文件(通常位于/etc/nginx/nginx.conf/etc/nginx/sites-available/default),添加以下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 添加上游服务器配置
upstream jupyter_server {
server localhost:8878;
keepalive 32;
}

server {
listen 80;
server_name example.com;

# 处理根路径重定向
location = /groot {
rewrite ^/(.*)$ /$1/ permanent;
}

# 处理静态文件
location /groot {
try_files $uri @proxy_jupyter;
}

# 代理到Jupyter服务器
location @proxy_jupyter {
proxy_pass http://jupyter_server;
proxy_read_timeout 300s;
proxy_set_header Host $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;
}

# WebSocket支持(用于Jupyter的交互式功能)
location ~ /groot/api/kernels/ {
proxy_pass http://jupyter_server;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade "websocket";
proxy_set_header Connection "Upgrade";
proxy_read_timeout 86400;
}

# 终端支持
location ~ /groot/terminals/ {
proxy_pass http://jupyter_server;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade "websocket";
proxy_set_header Connection "Upgrade";
proxy_read_timeout 86400;
}
}

2. HTTPS配置

如果使用HTTPS,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
server {
listen 443 ssl;
server_name example.com;

# SSL配置
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

# 其他配置与HTTP相同
# ...
}

# 重定向HTTP到HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}

3. 多Jupyter实例配置

如果需要在同一服务器上运行多个Jupyter实例,可以使用不同的端口和子路径:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# 第一个Jupyter实例
upstream jupyter_server1 {
server localhost:8878;
keepalive 32;
}

# 第二个Jupyter实例
upstream jupyter_server2 {
server localhost:8879;
keepalive 32;
}

server {
listen 80;
server_name example.com;

# 第一个实例
location = /jupyter1 {
rewrite ^/(.*)$ /$1/ permanent;
}

location /jupyter1 {
try_files $uri @proxy_jupyter1;
}

location @proxy_jupyter1 {
proxy_pass http://jupyter_server1;
# 其他代理配置...
}

# WebSocket支持
location ~ /jupyter1/api/kernels/ {
proxy_pass http://jupyter_server1;
# WebSocket配置...
}

# 第二个实例
location = /jupyter2 {
rewrite ^/(.*)$ /$1/ permanent;
}

location /jupyter2 {
try_files $uri @proxy_jupyter2;
}

location @proxy_jupyter2 {
proxy_pass http://jupyter_server2;
# 其他代理配置...
}

# WebSocket支持
location ~ /jupyter2/api/kernels/ {
proxy_pass http://jupyter_server2;
# WebSocket配置...
}
}

启动服务

1. 启动Jupyter服务

1
2
3
4
5
# 后台启动
nohup jupyter notebook > jupyter.log 2>&1 &

# 或使用systemd管理
sudo systemctl start jupyter.service

2. 重启Nginx

1
sudo systemctl restart nginx

访问Jupyter

现在,您可以通过以下URL访问Jupyter Notebook:

1
2
3
http://example.com/groot
# 或HTTPS
https://example.com/groot

安全配置

1. 设置密码

在生产环境中,建议设置密码保护:

1
2
# 生成密码哈希
jupyter notebook password

然后在配置文件中启用密码:

1
2
3
4
c.NotebookApp.password_required = True
# 注释掉以下行
# c.NotebookApp.token = ''
# c.NotebookApp.password = ''

2. IP限制

在Nginx配置中添加IP限制:

1
2
3
4
5
location /groot {
allow 192.168.1.0/24;
deny all;
try_files $uri @proxy_jupyter;
}

3. 使用HTTPS

在生产环境中,强烈建议使用HTTPS:

  • 使用Let’s Encrypt获取免费SSL证书
  • 配置Nginx使用HTTPS
  • 重定向HTTP请求到HTTPS

故障排除

1. 404错误

问题:访问子路径时出现404错误
解决方案

  • 检查Jupyter的base_url配置是否与Nginx的location匹配
  • 确保Nginx配置中的proxy_pass指向正确的端口

2. WebSocket连接失败

问题:Jupyter中的交互式功能无法使用
解决方案

  • 确保Nginx配置中包含WebSocket支持
  • 检查防火墙是否允许WebSocket连接

3. 权限错误

问题:Jupyter无法创建或保存文件
解决方案

  • 确保Jupyter运行用户对工作目录有读写权限
  • 检查文件系统权限设置

4. 502 Bad Gateway

问题:Nginx返回502错误
解决方案

  • 检查Jupyter服务是否正在运行
  • 验证Jupyter端口是否正确
  • 检查防火墙是否阻止连接

高级配置

1. 使用JupyterLab

如果使用JupyterLab,配置类似:

1
2
3
4
5
# JupyterLab配置
c.ServerApp.port = 8878
c.ServerApp.base_url = '/groot'
c.ServerApp.ip = '0.0.0.0'
c.ServerApp.open_browser = False

2. 自定义主题

您可以使用Jupyter的主题扩展:

1
2
3
4
5
# 安装主题
pip install jupyterthemes

# 应用主题
jt -t monokai -f roboto -fs 12 -nfs 12 -tfs 12 -ofs 12

3. 添加环境变量

在启动Jupyter时,可以设置环境变量:

1
2
3
4
5
6
# 设置环境变量
export JUPYTER_PORT=8878
export JUPYTER_BASE_URL=/groot

# 启动Jupyter
jupyter notebook

实际应用示例

示例1:使用Docker部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# docker-compose.yml
version: '3'
services:
jupyter:
image: jupyter/datascience-notebook
ports:
- "8878:8888"
volumes:
- ./notebooks:/home/jovyan/work
environment:
- JUPYTER_BASE_URL=/groot
- JUPYTER_TOKEN=
command:
- jupyter
- notebook
- --ip=0.0.0.0
- --no-browser
- --NotebookApp.base_url=/groot
- --NotebookApp.token=

nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- jupyter

示例2:使用systemd管理Jupyter

创建/etc/systemd/system/jupyter.service文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Unit]
Description=Jupyter Notebook
After=network.target

[Service]
Type=simple
User=username
ExecStart=/usr/bin/jupyter notebook --config=/home/username/.jupyter/jupyter_notebook_config.py
WorkingDirectory=/home/username/notebooks
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

启动并启用服务:

1
2
3
sudo systemctl daemon-reload
sudo systemctl start jupyter
sudo systemctl enable jupyter

总结

通过本文的配置,您可以成功地使用Nginx配置Jupyter Notebook的子路径访问,实现更灵活的服务部署。这种配置方式特别适合在同一服务器上托管多个服务的场景,使您能够通过不同的子路径访问不同的服务。

在实际应用中,建议根据具体的环境和需求进行适当的调整,确保服务的安全性和稳定性。同时,定期更新Jupyter和Nginx到最新版本,以获得最佳的性能和安全性。

参考资料