You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker中Jupyter Notebook信任状态不一致问题排查

Docker中Jupyter Notebook信任状态异常问题

背景信息

我有一个Docker镜像,内置两个.ipynb笔记本,启动容器时会运行这两个笔记本。

Dockerfile中复制并信任笔记本的步骤:

USER root
RUN mkdir -p $NOTEBOOK_DIR
COPY /PATH/TO/NOTEBOOK/NB1.ipynb $NOTEBOOK_DIR
COPY /PATH/TO/NOTEBOOK/NB2.ipynb $NOTEBOOK_DIR
RUN chown -R $NB_USER:$NB_GID $NOTEBOOK_DIR

USER $NB_UID
WORKDIR $HOME
RUN jupyter trust $NOTEBOOK_DIR/NB1.ipynb
RUN jupyter trust $NOTEBOOK_DIR/NB2.ipynb

启动脚本start-notebooks.sh内容:

#!/bin/bash
set -e
NB_PASS=$(echo ${SOME_ID} | python3.8 -c 'from notebook.auth import passwd;print(passwd(input()))')

# Run notebooks
jupyter trust $NOTEBOOK_DIR/NB1.ipynb
jupyter trust $NOTEBOOK_DIR/NB2.ipynb

jupyter-notebook --no-browser --ip 0.0.0.0 --port 8888 --NotebookApp.allow_origin='*' \
--NotebookApp.allow_remote_access=True --NotebookApp.quit_button=False --NotebookApp.terminals_enabled=False \
--NotebookApp.trust_xheaders=True --NotebookApp.open_browser=False --NotebookApp.notebook_dir=$NOTEBOOK_DIR \
--NotebookApp.password=${NB_PASS}

容器启动后输出:

my_user@my_host:~$ docker run -it --rm -p 8888:8888 --expose 8888 -v /efs/PATH/TO/NOTEBOOK_FILES:/efs/PATH/TO/NOTEBOOK_FILES -e BASE_PATH=/efs/PATH/TO/BASE_PATH -e SOME_ID=fd283b38-3e4a-11eb-a205-7085c2c5e519 notebooks-image:latest

**Notebook already signed: /home/nb_user/notebooks/NB1.ipynb**
/home/nb_user/.local/lib/python3.8/site-packages/nbformat/__init__.py:92: MissingIDFieldWarning: Code cell is missing an id field, this will become a hard error in future nbformat versions. You may want to use `normalize()` on your notebooks before validations (available since nbformat 5.1.4). Previous versions of nbformat are fixing this issue transparently, and will stop doing so in the future.
  validate(nb)
**Signing notebook: /home/nb_user/notebooks/NB2.ipynb**
[I 11:40:10.051 NotebookApp] Writing notebook server cookie secret to /home/nb_user/.local/share/jupyter/runtime/notebook_cookie_secret
[I 11:40:10.303 NotebookApp] [jupyter_nbextensions_configurator] enabled 0.6.1
[I 2022-12-11 11:40:10.507 LabApp] JupyterLab extension loaded from /home/nb_user/.local/lib/python3.8/site-packages/jupyterlab
[I 2022-12-11 11:40:10.507 LabApp] JupyterLab application directory is /home/nb_user/.local/share/jupyter/lab
[I 11:40:10.513 NotebookApp] Serving notebooks from local directory: /home/nb_user/notebooks
[I 11:40:10.513 NotebookApp] Jupyter Notebook 6.5.2 is running at:
[I 11:40:10.513 NotebookApp] http://my_host:8888/
[I 11:40:10.513 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[I 11:59:33.290 NotebookApp] 302 GET / (192.168.x.x) 1.300000ms
[W 11:59:33.303 NotebookApp] Clearing invalid/expired login cookie username-my_host-8888
[I 11:59:33.304 NotebookApp] 302 GET /tree? (192.168.x.x) 2.570000ms
[W 11:59:43.120 NotebookApp] Not allowing login redirect to '/tree?'
[I 11:59:43.120 NotebookApp] 302 POST /login?next=%2Ftree%3F (192.168.x.x) 63.300000ms
[I 11:59:43.191 NotebookApp] 302 GET / (192.168.x.x) 1.130000ms
/home/nb_user/.local/lib/python3.8/site-packages/nbformat/__init__.py:92: MissingIDFieldWarning: Code cell is missing an id field, this will become a hard error in future nbformat versions. You may want to use `normalize()` on your notebooks before validations (available since nbformat 5.1.4). Previous versions of nbformat are fixing this issue transparently, and will stop doing so in the future.
  validate(nb)
[W 11:59:47.222 NotebookApp] **Notebook NB2.ipynb is not trusted**

现象

在Jupyter Notebook GUI中打开NB1时,它已处于信任状态可直接使用;但打开NB2时,会弹出“Notebook not trusted”提示。已知容器中两个笔记本的所有权与权限完全相同。

问题

  1. 当前的操作流程是否存在问题?
  2. 若流程无问题,为何NB1可信而NB2不可信?

解答

问题1:流程存在冗余且潜在风险

当前流程有两处明显问题:

  • 重复执行jupyter trust:Dockerfile构建阶段已经以$NB_UID用户身份执行了信任操作,启动脚本中再次执行属于冗余操作。更关键的是,如果容器启动时笔记本文件被挂载卷覆盖(比如你的命令中挂载了/efs/PATH/TO/NOTEBOOK_FILES),构建阶段的信任签名会失效,因为文件内容或元数据已变化。
  • 挂载卷可能覆盖镜像内文件:你的docker run命令挂载了外部卷,若卷内存在同名的NB2.ipynb,会直接覆盖镜像中已经签名的版本,导致启动时虽然执行了jupyter trust,但可能因为文件权限、签名时机或文件内容差异出现信任失败。

问题2:NB1可信而NB2不可信的核心原因

从容器输出看,启动时NB1显示“Notebook already signed”,说明镜像内的NB1没有被挂载卷覆盖,保留了构建阶段的签名;而NB2显示“Signing notebook”,但之后仍提示不信任,大概率是以下情况之一:

  1. 挂载卷覆盖了NB2:外部卷中的NB2.ipynb没有签名,启动时执行jupyter trust可能因为文件所有者问题(比如卷内文件属主是root,而容器内以$NB_UID用户执行签名时权限不足,签名未成功写入)。
  2. NB2本身的格式问题:容器输出中NB2触发了MissingIDFieldWarning,说明笔记本缺少代码cell的ID字段。Jupyter的信任机制依赖笔记本的结构完整性,格式异常可能导致签名无法被正确识别。
  3. 签名时机差异:启动脚本中执行jupyter trust后立刻启动Notebook服务,可能存在文件缓存问题,NB2的签名还未写入磁盘就被服务读取,导致服务未识别到签名。

修复建议

  1. 移除Dockerfile或启动脚本中的重复信任操作:推荐只在启动脚本中执行jupyter trust,确保操作针对的是容器内最终的笔记本文件。
  2. 确保挂载卷文件权限正确:执行chown -R $NB_USER:$NB_GID $NOTEBOOK_DIR在启动脚本中(在jupyter trust之前),避免卷内文件属主不匹配导致签名失败。
  3. 修复笔记本格式:对NB2.ipynb执行jupyter nbformat --normalize NB2.ipynb,补全缺失的cell ID字段,解决格式警告问题。
  4. 增加签名后的延迟或文件同步:在启动脚本中jupyter trust之后添加sync命令,确保签名写入磁盘后再启动Notebook服务。

内容的提问来源于stack exchange,提问作者pugi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 15:25:14