【JupyterLab】内网Docker部署教程
使用docker compose快速部署JupyterLab,包括拉取基础镜像,制作内置新插件的新镜像
基础镜像部署
基础镜像选择scipy-notebook:latest,内置了python3和一些基础的数据科学的库(选择它主要是内置的包比较常用)
1. 项目结构
先创建工作目录与挂载卷
mkdir ~/deploy/jupyterlab-docker/{notebooks,config}
cd ~/deploy/jupyterlab-docker
2. 核心配置文件
创建docker-compose.yaml
services:
jupyterlab:
image: jupyterlab:v4_mod # 使用你的离线镜像(已含插件)
# image: quay.io/jupyter/scipy-notebook:latest # 基础镜像
container_name: jupyterlab
user: root
ports:
- "8888:8888"
environment:
- JUPYTER_TOKEN=${JUPYTER_TOKEN:-123456}
- CHOWN_HOME=yes
- CHOWN_HOME_OPTS=-R
- GRANT_SUDO=yes
# Python 包离线安装配置
- PIP_NO_INDEX=1 # 外网pip直接安装时暂时注释
- PIP_FIND_LINKS=/opt/packages
- PIP_TARGET=/opt/python-packages
- PYTHONPATH=/opt/python-packages:$PYTHONPATH
- PATH=/opt/python-packages/bin:$PATH
# 可选:主题配置持久化
- JUPYTER_CONFIG_DIR=/home/jovyan/.jupyter-config
volumes:
# 代码工作区
- ./notebooks:/home/jovyan/work
# 离线 Python 包
- ./packages:/opt/packages:ro
# Python 包持久化(核心)
- python_pkgs:/opt/python-packages
# Jupyter 配置持久化(主题设置、快捷键等 - 可选但推荐)
- jupyter_config:/home/jovyan/.jupyter-config
working_dir: /home/jovyan/work
entrypoint: >
bash -c "
mkdir -p /opt/python-packages /home/jovyan/.jupyter-config &&
chown -R 1000:100 /opt/python-packages /home/jovyan/.jupyter-config &&
echo '目录权限设置完成,正在启动 JupyterLab...' &&
# 启动时自动安装 requirements.txt 中的包(如果还没装)
if [ -f /opt/packages/requirements.txt ]; then
echo '正在从离线包安装依赖...' && \
/opt/conda/bin/python -m pip install --no-index --find-links=/opt/packages -r /opt/packages/requirements.txt || true
fi && \
# 使用 sudo 切换到 jovyan 用户运行(root 使用 sudo -u 不需要密码)
exec sudo -E -u jovyan bash -c '
export PATH=/opt/python-packages/bin:/opt/conda/bin:/usr/local/bin:/usr/bin:/bin
export PYTHONPATH=/opt/python-packages
export HOME=/home/jovyan
cd /home/jovyan/work
jupyter lab
--ip=0.0.0.0
--port=8888
--no-browser
--ServerApp.token=${JUPYTER_TOKEN}
--ServerApp.root_dir=/home/jovyan/work
'
"
restart: unless-stopped
volumes:
python_pkgs:
jupyter_config: # 保存你选择的黑色主题等个性化设置
创建.env文件
# ==========================================
# JupyterLab 基础配置
# ==========================================
# 访问密钥(Token):访问 http://localhost:8888 时输入这个密钥登录
JUPYTER_TOKEN=123456
# 登录密码哈希(可选):如果你想用"密码"代替"Token"登录
# JUPYTER_PASSWORD_HASH=sha1:xxxxxxxxx
# ==========================================
# 用户权限配置(与宿主机用户保持一致)
# ==========================================
# 宿主机用户ID(在终端运行 `id -u` 查看,通常是 1000)
PUID=1000
# 宿主机组ID(在终端运行 `id -g` 查看,通常是 1000)
PGID=1000
# Jupyter 容器内部使用的UID/GID(与PUID/PGID保持一致)
NB_UID=1000
NB_GID=1000
# ==========================================
# 可选配置
# ==========================================
# 时区设置(可选,默认UTC)
TZ=Asia/Shanghai
PYTHONPATH=
3. 快速启动
注意,v1版本的docker-compose命令是带横杠的,不带横杠的是v2版本
拉取镜像(如国内网络慢,先配置镜像源)
docker compose pull
启动服务
docker compose up -d
访问 http://<你的服务器IP>:8888,输入 token 或密码即可
内置新插件的镜像制作
可以先进到jupyterlab里面看看最新版的scipy-notebook镜像自带了哪些插件
!jupyter --version
Selected Jupyter core packages...
IPython : 9.9.0
ipykernel : 7.1.0
ipywidgets : 8.1.8
jupyter_client : 8.8.0
jupyter_core : 5.9.1
jupyter_server : 2.17.0
jupyterlab : 4.5.3
nbclient : 0.10.4
nbconvert : 7.16.6
nbformat : 5.10.4
notebook : 7.5.2
qtconsole : not installed
traitlets : 5.14.3
!jupyter labextension list
JupyterLab v4.5.3
/opt/conda/share/jupyter/labextensions
jupyterlab_pygments v0.3.0 enabled OK (python, jupyterlab_pygments)
jupyter-matplotlib v0.12.0 enabled OK
nbdime-jupyterlab v3.0.3 enabled OK
@jupyter-notebook/lab-extension v7.5.2 enabled OK
@jupyter-widgets/jupyterlab-manager v5.0.15 enabled OK (python, jupyterlab_widgets)
@jupyterlab/git v0.51.4 enabled OK (python, jupyterlab-git)
可以看到有git和jupyter-matplotlib了,我们安装的时候不用重复安装,插件的话推荐支持pip直接安装的,可以直接预构建,不用配置npm和node环境
确定好你的plugin list的时候,这时候可以新建Dockerfile了
FROM quay.io/jupyter/scipy-notebook:latest
USER root
# pip安装, _install plugins only - 预构建版本,无需 node/npm_
# 安装指定插件,合并RUN指令减少镜像层数
RUN pip install --no-cache-dir \
# 单元格运行时间
jupyterlab-execute-time \
# 代码格式化(含black/isort依赖)
jupyterlab-code-formatter black isort \
# 黑色主题
jupyterlab_materialdarker \
# Excel预览
jupyterlab-spreadsheet-editor \
# 系统资源监控
jupyter-resource-usage
# 如果是预构建插件(prebuilt),不需要 jupyter lab build
# 验证安装
RUN echo "=== 验证插件安装 ===" && \
# 验证安装(双重验证:前端扩展+服务端扩展)
jupyter labextension list && \
jupyter server extension list && \
# 确保安装的文件归属 jovyan 用户(避免权限问题)
chown -R jovyan:users /opt/conda/lib/python3.*/site-packages && \
chown -R jovyan:users /opt/conda/share/jupyter
# 预配置代码格式化器(创建默认配置)
RUN mkdir -p /etc/jupyter && \
echo 'c.JupyterLabCodeFormatter.default_formatter = {"python": "black"}' >> /etc/jupyter/jupyter_config.py
USER jovyan
开始构建,新镜像的名字可以随便起。构建的时间可能稍微有点长…
docker build -t jupyterlab:mod .
查看我们构建的新镜像,可以看到体积也相应地增大了
william@DESKTOP:~/deploy/jupyterlab-docker$ docker images | grep -E "note|lab"
jupyterlab:v4_mod 3ca87e52420f 4.83GB 0B U
quay.io/jupyter/scipy-notebook:latest d3b700424ea9 3.64GB 0B
内网部署
导出镜像
docker save jupyterlab:mod | gzip > jupyterlab_mod.tar.gz
通过FTP,或者U盘等介质,把镜像拷贝到内网机器,载入镜像
docker load -i jupyterlab_mod.tar.gz
安装额外的Python包
外网部署的jupyterlab想安装额外的包,直接在docker内的terminal或者jupyter里面的cell执行安装命令即可
pip install xxx
内网环境可以配置内网pip镜像源,此处省略
这里着重讲一下离线环境下安装python包,核心思路是:使用 PIP_TARGET 指定持久化目录 + 离线包挂载。相信在前面的docker-compose.yaml配置中你已经发现了端倪 ~
1. 外网准备离线包
在外网机器上执行(需要 Docker 环境):
mkdir -p jupyter_offline
cd jupyter_offline
# 创建 requirements.txt,列出你需要的包
cat > requirements.txt <<EOF
oracledb
EOF
# 下载所有依赖包(包括子依赖)到 packages 目录
mkdir -p packages
docker run --rm -v $(pwd)/packages:/packages -v $(pwd)/requirements.txt:/requirements.txt \
quay.io/jupyter/scipy-notebook:latest \
pip download -r /requirements.txt -d /packages
# 打包传输到内网
tar czf jupyter_offline.tar.gz packages requirements.txt
# 传到内网的 ~/jupyterlab-docker/ 目录下解压
2. 内网 Docker Compose 配置
和文章开头给的compose配置一致,这里只做解读,首先是环境变量
# 关键配置:离线安装 + 持久化目标
- PIP_NO_INDEX=1 # 强制离线模式(防止尝试连接外网)
- PIP_FIND_LINKS=/opt/packages # 从挂载目录找包
- PIP_TARGET=/opt/python-packages # 安装到这个目录(持久化)
- PYTHONPATH=/opt/python-packages:$PYTHONPATH # Python 能识别这些包
- JUPYTER_PATH=/opt/python-packages/share/jupyter:$JUPYTER_PATH
- PATH=/opt/python-packages/bin:$PATH
entrypoint执行命令,注意python需要使用绝对路径,避免docker内出现找不到命令的情况
mkdir -p /opt/python-packages /home/jovyan/.jupyter-config &&
chown -R 1000:100 /opt/python-packages /home/jovyan/.jupyter-config &&
echo '目录权限设置完成,正在启动 JupyterLab...' &&
# 启动时自动安装 requirements.txt 中的包(如果还没装)
if [ -f /opt/packages/requirements.txt ]; then
echo '正在从离线包安装依赖...' && \
/opt/conda/bin/python -m pip install --no-index --find-links=/opt/packages -r /opt/packages/requirements.txt || true
fi && \
3. 在内网使用(关键操作)
首次启动
# 把外网传进来的 packages 目录和 requirements.txt 放在 docker-compose.yml 同目录
docker compose up -d
# 查看日志确保离线包已自动安装
docker compose logs -f
后续在容器内手动安装新包(持久化)
在 JupyterLab 的 Terminal 中执行:
# 安装离线目录中的特定包
pip install /opt/packages/some-package.whl
# 或者如果你更新了 requirements.txt 并挂载了新的 packages:
pip install --no-index --find-links=/opt/packages requests
# 注意:因为 PIP_TARGET 和 PYTHONPATH 已设置,这些包会自动进入持久化目录 /opt/python-packages
# 即使 docker restart,这些包依然存在
验证持久化是否生效
# 在容器内安装一个新包,比如(假设你有这个离线包)
docker compose exec jupyterlab pip install --no-index --find-links=/opt/packages click
# 重启容器
docker compose restart
# 进入容器检查包是否还在
docker compose exec jupyterlab python -c "import click; print('持久化成功:', click.__file__)"
# 应该输出: /opt/python-packages/click/...
4. 进阶:添加新的离线包(迭代更新)
如果内网运行一段时间后,你需要增加新的包:
外网:
# 下载新包
docker run --rm -v $(pwd)/packages:/packages quay.io/jupyter/scipy-notebook:latest \
pip download new-package-name -d /packages
# 重新 tar 传到内网,覆盖 packages 目录
内网:
# 替换 packages 目录后
docker compose exec jupyterlab pip install --no-index --find-links=/opt/packages new-package-name
# 无需重启,立即生效,且已持久化
方案优势说明
- 分离镜像与包:基础镜像保持干净,所有额外包放在独立持久化卷中
- 支持离线:
PIP_NO_INDEX=1确保不会尝试连接外网,纯离线安装 - 重启不丢失:包安装在
python_pkgs命名卷中,即使docker rm删除容器,卷还在 - 用户无感知:Jupyter 用户不需要知道背后的机制,正常使用
pip install即可(受限于离线源),且安装的包自动持久化
注意:如果遇到权限问题(比如某些包需要编译),因为启动命令中有 chown -R jovyan:users /opt/python-packages,通常 jovyan 用户可以正常写入该目录。
更多推荐
所有评论(0)