在 Ubuntu 系统上部署 JupyterHub、JupyterLab 和 DockerSpawner 的详细方案,涵盖环境准备、安装、配置和部署步骤。目标是创建一个多用户 Jupyter 环境,每个用户通过 DockerSpawner 运行独立的 JupyterLab 容器,确保隔离性和可扩展性。本方案基于官方文档和社区最佳实践,也适用于 Ubuntu 20.04 或 22.04。
总体上分两种情况,一种是直接在服务器上启动JupyterHub,另一种是在docker中启动JupyterHub,后者隔离效果更好,推荐使用,但是绑定服务器目录时需要注意。以下方案中会作出区分说明。
1. 环境准备
1.1 系统要求
- 操作系统:Ubuntu 20.04 LTS 或 22.04 LTS(推荐服务器版)。
- 硬件要求:
- 最低配置:2核CPU,4GB内存,20GB磁盘空间。
- 推荐配置:4核CPU,8GB内存,50GB+磁盘空间(根据用户数量和数据存储需求调整)。
- 网络:确保服务器可以访问互联网以拉取 Docker 镜像和安装依赖。
- 权限:需要 root 或 sudo 权限。
1.2 安装基本工具
更新系统并安装必要的工具:
bash
sudo apt update && sudo apt upgrade -y
下面这一步并非必要,主要用于在服务器上直接启动JupyterHub。
bash
sudo apt install -y curl git python3 python3-pip python3-venv
1.3 安装 Docker
安装 Docker 和 Docker Compose,用于运行 JupyterHub 和用户容器:
bash
# 安装 Docker
sudo apt install -y docker.io
sudo systemctl start docker
sudo systemctl enable docker
# 验证 Docker 安装
docker --version
# 安装 Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# 验证 Docker Compose 安装
docker-compose --version
# 将当前用户添加到 docker 组(避免每次使用 docker 需要 sudo)
sudo usermod -aG docker $USER
newgrp docker
上面这一步需要重新登录或者重启才能生效。其中docker-compose也可以不装,新版的docker中自带docker compose命令。
2. 安装 JupyterHub 和依赖(这是服务器直接部署JupyterHub,使用docker的话可以跳过)
2.1 创建虚拟环境
为了隔离 JupyterHub 的 Python 依赖,创建一个虚拟环境:
bash
python3 -m venv /opt/jupyterhub
source /opt/jupyterhub/bin/activate
2.2 安装 JupyterHub 和 DockerSpawner
在虚拟环境中安装 JupyterHub 和相关包:
bash
pip install --upgrade pip
pip install jupyterhub jupyterlab dockerspawner
- jupyterhub:核心服务,用于管理多用户环境。
- jupyterlab:为用户提供 JupyterLab 界面。
- dockerspawner:用于在 Docker 容器中启动单用户 JupyterLab 实例。
2.3 安装 Node.js(可选,JupyterLab 依赖)
JupyterLab 需要 Node.js 来支持扩展和前端功能:
bash
sudo apt install -y nodejs npm
3. 配置 JupyterHub(这个配置文件是用于服务器直接部署,docker部署的话其中的设置有所区别)
3.1 创建 JupyterHub 配置文件
生成默认配置文件(也可以跳过,直接复制下面的配置文件内容进去,默认配置文件很长,看起来不方便):
bash
mkdir /opt/jupyterhub
jupyterhub --generate-config -f /opt/jupyterhub/jupyterhub_config.py
配置文件位于 /opt/jupyterhub/etc/jupyterhub_config.py,以下是关键配置步骤。
3.2 配置 DockerSpawner
编辑 jupyterhub_config.py,添加以下内容以启用 DockerSpawner 和 JupyterLab:
python
c = get_config()
import os
import sys
from dockerspawner import DockerSpawner
# 设置 DockerSpawner
c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner'
c.DockerSpawner.image = 'jupyter/minimal-notebook:x86_64-python-3.11.6'
c.DockerSpawner.network_name = 'jupyterhub-network'
# 设置 JupyterLab 作为默认界面
c.Spawner.default_url = '/lab'
# 持久化存储配置
notebook_dir = '/home/jovyan/work'
c.DockerSpawner.notebook_dir = notebook_dir
c.DockerSpawner.volumes = {
'/mnt/raid/jupyterhub_persistent/{username}': notebook_dir,
'/mnt/raid/jupyterhub_shared': '/home/jovyan/shared'
}
# 上面路径中的/mnt/raid是我自己服务器的一个地址,可以替换。注意这个地址不管在服务器直接运行JupyterHub还是在docker中,都是设置为服务器上的地址,因为是绑定给用户容器的。
# 动态创建用户目录
def create_dir_hook(spawner):
username = spawner.user.name
volume_path = os.path.join('/mnt/raid/jupyterhub_persistent', username)
if not os.path.exists(volume_path):
os.mkdir(volume_path, 0o755)
os.chown(volume_path, 1000, 100) # jovyan 用户的 UID 和 GID
c.Spawner.pre_spawn_hook = create_dir_hook
# 资源限制
c.DockerSpawner.extra_host_config = {
'mem_limit': '16g', # 每个容器 64GB,10 个用户平分 640GB
'cpu_period': 100000,
'cpu_quota': 1000000, # 每个容器 1 核心,10 个用户共 10 核心
}
# 如果本地端口有冲突可以设置,否则不设置
c.JupyterHub.bind_url = 'http://:8090'
c.JupyterHub.hub_connect_ip = '127.0.0.1'
c.JupyterHub.hub_ip = '0.0.0.0'
c.JupyterHub.hub_port = 9000
# 可选:设置认证,根据需要选择认证方式,建议用这种自定义用户比较方便,不用系统的用户
c.JupyterHub.authenticator_class = 'nativeauthenticator.NativeAuthenticator'
c.NativeAuthenticator.enable_signup = True
c.NativeAuthenticator.open_signup = True
c.Authenticator.admin_users = {'admin'}
# 可选:自动停止闲置服务器
c.JupyterHub.services = [
# {
# 'name': 'cull_idle',
# 'admin': True,
# 'command': 'python3 /opt/jupyterhub/cull_idle_servers.py --timeout=3600'.split(),
# },
{
"name": "jupyterhub-idle-culler-service",
"command": [
sys.executable,
"-m", "jupyterhub_idle_culler",
"--timeout=3600",
],
"admin": True,
}
]
3.3 创建 Docker 网络
为 JupyterHub 和用户容器创建一个专用的 Docker 网络:
bash
docker network create jupyterhub-network
3.4 配置认证
JupyterHub 默认使用 PAM 认证(基于系统用户)。若需要简单测试,可以配置 Native Authenticator 允许用户自注册:
bash
pip install jupyterhub-nativeauthenticator
在 jupyterhub_config.py 中添加:
python
c.JupyterHub.authenticator_class = 'nativeauthenticator.NativeAuthenticator'
c.Authenticator.admin_users = {'admin'} # 设置管理员用户
若使用其他认证方式(如 OAuth、LDAP),请参考 JupyterHub 官方文档配置对应 Authenticator。
3.5 数据持久化
为确保用户数据持久化,DockerSpawner 使用 Docker 卷(如上配置)。每个用户的卷命名为 jupyterhub-user-{username},存储在 /home/jovyan/work 目录。
若需要共享数据目录,可以挂载主机路径:
python
c.DockerSpawner.volumes = {
'jupyterhub-user-{username}': notebook_dir,
'/path/on/host/shared': '/home/jovyan/shared'
}
确保主机路径权限正确:
bash
sudo chown :1000 /path/on/host/shared
sudo chmod g+rws /path/on/host/shared
sudo setfacl -d -m g::rwx /path/on/host/shared
4. 使用 Docker Compose 部署
为简化管理,使用 Docker Compose 部署 JupyterHub 和相关服务。
4.1 创建 docker-compose.yml
在 /opt/jupyterhub 目录下创建 docker-compose.yml:
yaml
version: '3.8'
services:
jupyterhub:
build:
context: .
dockerfile: Dockerfile
container_name: jupyterhub
restart: unless-stopped
ports:
- "9000:8000"
volumes:
- /opt/jupyterhub/srv:/srv/jupyterhub # 这里单独设置了一个srv以跟docker中的srv对应,区别于服务器直接部署的配置,测试时方便区分
- /var/run/docker.sock:/var/run/docker.sock
- /mnt/raid/jupyterhub/jupyterhub_persistent:/jupyterhub/jupyterhub_persistent
- /mnt/raid/jupyterhub/jupyterhub_shared:/jupyterhub/jupyterhub_shared
environment:
- DOCKER_HOST=unix:///var/run/docker.sock
- DOCKER_NOTEBOOK_IMAGE=jupyter/scipy-notebook:latest
- DOCKER_NETWORK_NAME=jupyterhub-network
networks:
- jupyterhub-network
networks:
jupyterhub-network:
external: true
用户环境定制
若需要自定义用户镜像,创建 Dockerfile:
因为启用了nativeauthenticator所以默认的镜像不行,需要自己通过Dockerfile加上。同时也指定自己的jupyterhub_config
Dockerfile
# Use the official JupyterHub base image
FROM jupyterhub/jupyterhub:latest
# Install dockerspawner and nativeauthenticator
RUN pip install --no-cache-dir \
dockerspawner \
jupyterhub-nativeauthenticator \
jupyterhub-idle-culler
# Create directory for persistent storage (if needed inside the hub container)
RUN mkdir -p /jupyterhub/jupyterhub_persistent /jupyterhub/jupyterhub_shared
RUN chmod -R 755 /jupyterhub
# Copy the jupyterhub_config.py into the container
COPY jupyterhub_config.py /srv/jupyterhub/jupyterhub_config.py
# Expose the default JupyterHub port
EXPOSE 8000
# Set working directory
WORKDIR /srv/jupyterhub
# Start JupyterHub
CMD ["jupyterhub", "-f", "/srv/jupyterhub/jupyterhub_config.py"]
4.2 用docker部署并启动 JupyterHub(这是方式二)
bash
cd /opt/jupyterhub
docker-compose up -d
4.3 验证部署
- 访问 http://<服务器IP>:8000,应看到 JupyterHub 登录页面。
- 使用管理员账户(如 admin)登录,测试创建用户和启动 JupyterLab 容器。
- 检查 Docker 容器:bash
docker ps
应看到 jupyterhub 容器和用户容器(如 jupyter-<username>)。
4.4 日志查看
若遇到问题,查看日志:
bash
docker logs jupyterhub
5. 高级配置
5.1 HTTPS 配置(不建议,建议另外通过caddy代理并设置ssl)
为生产环境,建议配置 HTTPS:
- 使用 Let’s Encrypt 获取免费 SSL 证书:bash
sudo apt install -y certbot python3-certbot-nginx certbot certonly --standalone -d <your-domain>
- 在 jupyterhub_config.py 中配置 SSL:python
c.JupyterHub.ssl_key = '/etc/letsencrypt/live/<your-domain>/privkey.pem' c.JupyterHub.ssl_cert = '/etc/letsencrypt/live/<your-domain>/fullchain.pem' c.JupyterHub.port = 443
- 更新 docker-compose.yml,将端口改为 443:443。
5.2 GPU 支持
若需要 GPU 支持,确保主机安装了 NVIDIA 驱动和 nvidia-container-toolkit:
bash
sudo apt install -y nvidia-driver-<version> nvidia-container-toolkit
在 jupyterhub_config.py 中添加:
python
c.DockerSpawner.extra_host_config = {'runtime': 'nvidia'}
使用支持 GPU 的镜像,如 jupyter/tensorflow-notebook。
5.3 用户环境定制
若需要自定义用户镜像,创建 Dockerfile:
dockerfile
FROM jupyter/scipy-notebook:latest
RUN pip install numpy pandas matplotlib
CMD ["jupyterhub-singleuser"]
构建并推送到 Docker Hub 或本地仓库:
bash
docker build -t my-jupyterlab-image .
docker tag my-jupyterlab-image <your-dockerhub-username>/my-jupyterlab-image:latest
docker push <your-dockerhub-username>/my-jupyterlab-image:latest
在 jupyterhub_config.py 中更新:
python
c.DockerSpawner.image = '<your-dockerhub-username>/my-jupyterlab-image:latest'
6. 常见问题排查
- “Spawn failed” 错误:
- 检查 docker logs jupyterhub 是否有 KeyError 或权限问题。
- 确保 Docker 网络 jupyterhub-network 已创建。
- 验证 DOCKER_NOTEBOOK_IMAGE 是否可拉取。
- 用户容器无法访问数据库:
- 确保数据库容器在同一 Docker 网络中:bash
docker network connect jupyterhub-network <database-container>
- 确保数据库容器在同一 Docker 网络中:bash
- 权限问题:
- 检查卷挂载路径权限,确保用户 jovyan(UID 1000)有写权限。
- JupyterLab 不显示:
- 确认 c.Spawner.default_url = ‘/lab’ 已设置。
- 确保镜像中已安装 JupyterLab:bash
docker run -it <image> pip show jupyterlab
7. 维护与备份
- 备份用户数据:
- 用户数据存储在 Docker 卷中,查看卷:bash
docker volume ls
- 备份卷:bash
docker run --rm -v jupyterhub-user-<username>:/data -v /backup:/backup busybox tar cvf /backup/user-<username>.tar /data
- 用户数据存储在 Docker 卷中,查看卷:bash
- 更新 JupyterHub:
- 停止服务:docker-compose down
- 更新镜像:docker pull jupyterhub/jupyterhub:latest
- 重新启动:docker-compose up -d
- 清理无用容器:bash
docker container prune
8. 参考资源
- JupyterHub 官方文档:https://jupyterhub.readthedocs.io
- DockerSpawner 文档:https://jupyterhub-dockerspawner.readthedocs.io
- Jupyter Docker Stacks:https://jupyter-docker-stacks.readthedocs.io
- GitHub – jupyterhub/jupyterhub-deploy-docker:https://github.com/jupyterhub/jupyterhub-deploy-docker[](https://github.com/jupyterhub/jupyterhub-deploy-docker)
- GitHub – jupyterhub/dockerspawner:https://github.com/jupyterhub/dockerspawner[](https://github.com/jupyterhub/dockerspawner)
通过以上步骤,您可以在 Ubuntu 上成功部署一个支持 JupyterLab 和 DockerSpawner 的 JupyterHub 环境,适合教学、科研或团队协作场景。如需进一步定制或遇到具体问题,请提供更多细节,我可以为您提供针对性指导!