自定义 Notebook 镜像构建

需要为平台 notebook(jupyter / vscode)构建、定制并上线新镜像(加插件、加 python/julia/R 内核、加大数据/深度学习环境)时读这篇

06-二次开发 / 镜像构建
notebookjupyterjupyterlabvscodetheia自定义镜像custom imageDockerfiledocker commitNOTEBOOK_IMAGESconda多pythonmulti-pythonipykerneljuliaR语言

自定义 Notebook 镜像构建

本篇汇总 CubeStudio 平台 notebook(JupyterLab / VSCode-Theia)镜像的构建与上线方法,以及 Pro / bigdata / deeplearning / machinelearning 等不同"风味"镜像的定制细节。

平台把所有可在线编辑的 Web 服务都抽象为 notebook。Jupyter 镜像构建目录在仓库 images/jupyter-notebook/,VSCode(Theia)镜像构建目录在 images/theia/

一、运行机制:续期、清理与环境持久化

  • 续期:GPU notebook 为独占方式占用 GPU,平台会定时清理,需按时续期。

  • 清理:定时清理由 Celery 定时任务 task.delete_notebook 控制。

    说明:myapp/config.py:708-712 中的 task_delete_notebook 定时任务默认已被注释(即开箱不启用定时清理);如需启用定时停止 notebook,取消该段注释即可(启用后调度为每日凌晨 4 点 crontab(minute='1', hour='4'))。

  • 环境持久化:notebook 重启后会自动执行启动脚本。后端实际拼接的启动前置命令为(见 myapp/views/view_notebook.py:558):

    (nohup sh /init.sh > /notebook_init.log 2>&1 &) ; (nohup sh /mnt/<用户名>/init.sh > /init.log 2>&1 &) ;
    

    其中 /init.sh 来自镜像(仓库 images/jupyter-notebook/init.sh),/mnt/<用户名>/init.sh 是用户个人持久化目录下的脚本。把环境安装命令写入 /mnt/<用户名>/init.sh,重启后即可自动安装;否则需要把环境打进镜像或使用离线 anaconda 文件。个人持久化目录为 /mnt/<用户名>

自定义 Notebook 的取舍:添加功能越多,启动/运行越慢。因此在提供功能丰富的 Pro 版本的同时,仍保留基础版本,满足不同用户需求。

二、三种镜像构建方法

构建新镜像并在生产上替换后,用户才能使用新的 notebook 镜像。

方法 1:Dockerfile 构建

Jupyter 镜像构建在仓库 images/jupyter-notebook/,VSCode 镜像构建在 images/theia/。基础 Dockerfile 可参考 images/jupyter-notebook/Dockerfile-ubuntu-baseDockerfile-ubuntu-conda

平台当前默认可选镜像见下文「四、上线到平台」。

方法 2:直接 commit 容器

先 run 一个容器,Web 界面里装插件/环境,再 docker commit 成镜像。

# 启动 jupyter
docker run --name jupyter -p 3000:3000 -d \
  ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-cpu-conda \
  jupyter lab --notebook-dir=/ --ip=0.0.0.0 --no-browser --allow-root --port=3000 \
  --NotebookApp.token='' --NotebookApp.password='' --NotebookApp.allow_origin='*'

# 启动 vscode(theia)
docker run --name vscode -p 3000:3000 -d \
  ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:vscode-ubuntu-cpu-conda \
  node /home/theia/applications/browser/src-gen/backend/main.js /home/project \
  --hostname=0.0.0.0 --port=3000

然后访问 http://<宿主机IP>:3000/,在 Web 界面安装 notebook 插件、pip/apt 环境等。环境完整后 commit 成镜像:

docker commit jupyter ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-cpu-base-1

方法 3:在用户已有镜像上叠加 jupyter

在用户原有 Docker 镜像的 Dockerfile 基础上追加:

FROM 原有镜像

# ...原有内容...

# jupyter 前后端
RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple
RUN pip install jupyterlab==3.4.8 notebook==6.4.12

# 安装启动 sshd 所需(按基础镜像系统调整)
RUN apt install -y openssh-server

# jupyter 命令行使用 bash
ENV SHELL=/bin/bash

# 拷贝 examples(ssh 连接使用),改为自己的本地代码地址
COPY images/jupyter-notebook/examples/* /examples/

# 拷贝安全防破解 pam 配置
COPY images/jupyter-notebook/pam/* /pam/

# 环境初始化配置
COPY images/jupyter-notebook/init.sh /init.sh

三、增加其他类型的 notebook

所有可提供在线编辑功能的 Web 服务都可定义为 notebook。开发代码已对外开放,需满足若干条件,其中关键是可配置 URL 前缀,用来区分不同的 notebook。

四、上线到平台(NOTEBOOK_IMAGES 配置)

config.py 中的 NOTEBOOK_IMAGES 变量为 notebook 可选镜像列表,更新此变量即可上线新镜像(bigdata / deeplearning / machinelearning / Pro 等所有风味镜像上线方式相同)。

当前默认配置(myapp/config.py:998 / install/docker/config.py:998,列表 [镜像地址, 显示名] 格式):

NOTEBOOK_IMAGES = [
    ['ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:vscode-ubuntu-cpu-conda-20260101', 'vscode-conda(cpu)'],
    ['ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:vscode-ubuntu-gpu-conda-20260101', 'vscode-conda(gpu)'],
    ['ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-cpu-conda', 'jupyter-conda(cpu)'],
    ['ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-gpu-conda', 'jupyter-conda(gpu)'],
    ['ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-cpu-pro', 'jupyter-conda-pro(cpu)'],
    ['ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-bigdata', 'jupyter(bigdata)'],
    ['ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-machinelearning', 'jupyter(machinelearning)'],
    ['ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-deeplearning', 'jupyter(deeplearning)'],
    ['ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:rstudio-ubuntu-bigdata', 'rstudio(bigdata)'],
]

说明:

  • 镜像仓库命名空间为 notebook-enterprise(商业版)。
  • 配置文件中还以注释形式给出了若干备选:国产芯片(昇腾 npu / 海光 dcu / 寒武纪 mlu / 沐曦 / 昆仑芯)、matlab、按框架+python+cuda 组织的 dict 格式(pytorch/tensorflow/mxnet/paddle/mindspore/deepspeed)、以及 arm64 专用列表,见 myapp/config.py:1026-1103
  • bigdata 镜像名需包含 bigdata,才会被识别为 bigdata 组件(命名约定,见下文「六」)。

五、conda 多版本 python

安装 conda(miniconda):

wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-latest-Linux-x86_64.sh
mkdir /root/.conda && bash Miniconda3-latest-Linux-x86_64.sh -b
rm -f Miniconda3-latest-Linux-x86_64.sh
export PATH=/root/miniconda3/bin:$PATH

创建新 python 版本并注册为 kernel:

conda create -y -n python36 python=3.6
source activate python36
conda config --append channels conda-forge
pip install jupyterlab ipykernel numpy pandas scipy matplotlib scikit-learn ipympl
python -m ipykernel install --user --name python36 --display-name "python3.6"

在 notebook 中检验版本:

import sys
print(sys.version)

六、GPU 监控

在 GPU 镜像上安装 nvdashboard:

# 以特权方式启动 gpu notebook
docker run --name jupyter --privileged=true -p 8081:3000 -d \
  ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-gpu-base \
  jupyter lab --notebook-dir=/ --ip=0.0.0.0 --no-browser --allow-root --port=3000 \
  --NotebookApp.token='' --NotebookApp.password='' --NotebookApp.allow_origin='*'

# 安装 gpu 监控能力
pip install jupyterlab-nvdashboard==0.8 bokeh==2.4 -i https://mirrors.aliyun.com/pypi/simple

七、Pro 镜像构建详解

Pro 镜像在 CPU/GPU 基础镜像之上,叠加大量插件、多语言内核(julia、R)、多 python 版本与自定义 kernel。源构建步骤见 images/jupyter-notebook/Dockerfile-ubuntu-cpu-pro.md

7.1 起容器

# 在 cpu 基础镜像上构建 pro 镜像
docker run --name jupyter --privileged=true -p 3000:3000 -d \
  ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-cpu-conda-amd64 \
  jupyter lab --notebook-dir=/ --ip=0.0.0.0 --no-browser --allow-root --port=3000 \
  --NotebookApp.token='' --NotebookApp.password='' --NotebookApp.allow_origin='*'

# 在 gpu 基础镜像上(同时暴露 8081->3000、8080->2000)
docker run --name jupyter --privileged=true -p 8081:3000 -p 8080:2000 -d \
  ccr.ccs.tencentyun.com/cube-studio/notebook-enterprise:jupyter-ubuntu-gpu-base \
  jupyter lab --notebook-dir=/ --ip=0.0.0.0 --no-browser --allow-root --port=3000 \
  --NotebookApp.token='' --NotebookApp.password='' --NotebookApp.allow_origin='*'

7.2 安装插件依赖组件

pip install jupyterlab==3.6.3 jupyter-client==7.0.6 jupyter_core==5.3.0 jupyter-events==0.6.3 jupyter-lsp==2.1.0 jupyter-resource-usage==0.7.2
pip install jupyterlab-git==0.41.0 jupyterlab-lsp==4.1.0 jupyterlab-pygments==0.2.2 jupyterlab_server==2.22.1 jupyterlab-system-monitor==0.8.0 jupyterlab-tensorboard-pro==0.7.0 jupyterlab-topbar==0.6.1
pip install jupyter-server==1.23.6 jupyter_server_fileid==0.9.0 jupyter-server-mathjax==0.2.6 jupyter_server_ydoc==0.8.0 jupyter-ydoc==0.2.4
pip install tensorflow==2.12.0 tensorboard==2.12.3
# arm64 架构改装:pip install tensorflow-aarch64==2.12.0

其它已带版本参考:jupyter_server_terminals 0.4.4jupyterlab_widgets 3.0.13

注意:每个插件对 jupyter 的版本要求不同,pip install 插件可能会重装 jupyterlab 版本,需留意。

可选安装更多 LSP / 代码提示插件:

# 查看已安装插件清单
cat /root/miniconda3/envs/python39/share/jupyter/lab/staging/package.json
# 进入每个虚拟环境安装 lsp
pip install -U jupyter-lsp python-lsp-server[all]
conda install -c conda-forge jupyterlab-lsp

(参考插件清单:debuggerkeplergl-jupyter 等。)

7.3 安装 julia

wget https://julialang-s3.julialang.org/bin/linux/x64/1.9/julia-1.9.0-linux-x86_64.tar.gz
tar -zxvf julia-1.9.0-linux-x86_64.tar.gz && rm julia-1.9.0-linux-x86_64.tar.gz
# arm 架构:julia-1.9.0-linux-aarch64.tar.gz
echo "export PATH=/julia-1.9.0/bin:\$PATH" >> /etc/profile
source /etc/profile
julia
# 在 julia 中:
using Pkg
Pkg.add("IJulia")

7.4 安装 R 语言与 IRkernel

apt update -y && apt install -y --no-install-recommends software-properties-common dirmngr \
  libcurl4-openssl-dev libssl-dev make libzmq3-dev openssl
wget -qO- https://cloud.r-project.org/bin/linux/ubuntu/marutter_pubkey.asc | tee -a /etc/apt/trusted.gpg.d/cran_ubuntu_key.asc
add-apt-repository "deb https://cloud.r-project.org/bin/linux/ubuntu $(lsb_release -cs)-cran40/"
apt install -y --no-install-recommends r-base r-base-dev

切到目标虚拟环境后安装 R kernel:

conda install -c conda-forge r-base
conda install -c r r-irkernel r-essentials
R
# 在 R 内(界面上出现 R kernel 也连不上时必须在 R 里装):
install.packages('IRkernel')          # 选北京镜像
IRkernel::installspec(user = FALSE)    # 在 R 中注册激活 R kernel
install.packages('devtools')
install.packages(c('repr', 'IRdisplay', 'evaluate', 'crayon', 'pbdZMQ', 'devtools', 'uuid', 'digest'))
install.packages("languageserver")

7.5 安装多个 python 版本(每个版本重复)

conda create -y -n python36 python=3.6
conda activate python36
conda config --append channels conda-forge
pip install jupyterlab ipykernel numpy pandas scipy matplotlib scikit-learn ipympl
pip install jupyterlab-lsp 'python-lsp-server[all]'
conda install -c conda-forge python-lsp-server r-languageserver
python -m ipykernel install --user --name python36 --display-name "python3.6"
jupyter labextension install @krassowski/jupyterlab-lsp

7.6 安装自定义特殊 python 环境(以 cube-studio kernel 为例)

conda create -y -n cube-studio python=3.9
source activate cube-studio
pip install jupyterlab ipykernel numpy pandas scipy matplotlib scikit-learn ipympl
pip install PySnooper==1.1.1 requests==2.28.1 Flask==2.1.3 kubernetes==21.7.0 celery==5.2.7 \
  redis==4.5.4 cryptography==38.0.4 tqdm==4.64.1 pyarrow==11.0.0 fsspec==2023.1.0 aiohttp==3.8.4 \
  librosa==0.9.2 pandarallel==1.6.5 requests_toolbelt==0.10.1 multiprocess gradio==3.34.0 \
  --index-url https://mirrors.aliyun.com/pypi/simple
python -m ipykernel install --user --name cube-studio --display-name "cube-studio"
# 修改 kernel 图标
docker cp logo-svg.svg jupyter:/root/.local/share/jupyter/kernels/cube-studio/

查看所有内核:

jupyter kernelspec list

八、bigdata 风味(hadoop / spark / hive / flink)

源:images/jupyter-notebook/bigdata/readme.md

组件版本(可自行更改):

组件 版本 备注
Hadoop 3.2.2 hadoop-3.2.2
Spark 3.1.3 spark-3.1.3-bin-hadoop3.2
Hive 3.1.2 apache-hive-3.1.2-bin
Flink 1.15.1 pyFlink
Python 3.8.12 notebook:jupyter-ubuntu-cpu-base 自带版本

8.1 修改 Hadoop/Hive 配置文件

修改 conf/hadoop/core-site.xmlhdfs-site.xmlyarn-site.xmlconf/hive/hive-site.xml

务必检查 yarn-site.xmlyarn.resourcemanager.address,否则默认 0.0.0.0:8032 会导致 JupyterLab 作业无法提交到 yarn:

<property>
    <name>yarn.resourcemanager.address</name>
    <value>xxx.xxx.xxx.xxx:8032</value>
</property>

notebook 容器自带环境变量,可用于访问 driver 与用户认证(实际由后端注入,见 myapp/views/view_notebook.py):

USERNAME=用户名
SERVICE_EXTERNAL_IP=notebook 代理 ip
PORT1=暴露端口1
PORT2=暴露端口2

8.2 添加测试示例

example 下添加 pyspark / pyflink / clickhouse / impala / presto / mysql / postgresql 等查询分析示例,或 Arrow 大内存分析、可视化分析示例。平台会自动把 example 软链到用户个人目录下。

8.3 构建并推送镜像

docker build --network=host -t $hubhost/notebook:jupyter-ubuntu-bigdata -f Dockerfile .
docker push $hubhost/notebook:jupyter-ubuntu-bigdata

命名约定:镜像名需包含 bigdata,才会被识别为 bigdata 组件。

8.4 上线

更新 config.pyNOTEBOOK_IMAGES(见「四」)。

九、deeplearning / machinelearning 风味

源:images/jupyter-notebook/deeplearning/readme.mdmachinelearning/readme.md。两者构建流程一致,仅 example 内容与镜像名不同。

  1. example 下添加常用深度学习 / 机器学习算法示例(平台自动软链到用户个人目录)。

  2. 构建并推送镜像:

    # deeplearning
    docker build --network=host -t $hubhost/notebook:jupyter-ubuntu-deeplearning -f Dockerfile .
    docker push $hubhost/notebook:jupyter-ubuntu-deeplearning
    
    # machinelearning
    docker build --network=host -t $hubhost/notebook:jupyter-ubuntu-machinelearning -f Dockerfile .
    docker push $hubhost/notebook:jupyter-ubuntu-machinelearning
    
  3. 更新 config.pyNOTEBOOK_IMAGES 上线(见「四」)。

最后更新 2026-07-09完整文档以官方仓库为准:GitHub Wiki