JupyterHub in Docker:定制环境
上一篇文章《JupyterHub In Docker:简单示例》介绍了使用 Docker 创建最简单的 JupyterHub 环境,为用户提供官方的 Jupyter 镜像。
本文进一步介绍如何为用户提供定制的 Jupyter 环境,并提供额外的功能。
概述
DockerSpawner 中可以配置使用的 Docker 镜像。
本文为 nwpc-oper/nwpc-graphics 项目构建 Docker 镜像,并内置 nwpc-oper/nwpc-data 库。
为了保存用户文件,将 notebook 目录使用 Docker volume 挂载,保证用户的数据不会丢失。
为了访问二级存储上的数据,需要将 /sstorage1 目录也同时挂载到 docker 容器中。
另外,绘图脚本因为版权问题,也无法直接放到 docker 容器中,所以也要挂载到容器中。
Hub 镜像
修改前一篇文章中 Hub 镜像的 jupyerhub_config.py
文件。
权限
使用 FirstUseAuthenticator 验证登录,用户在第一次登录时需要设置密码。
c.JupyterHub.authenticator_class = 'firstuseauthenticator.FirstUseAuthenticator'
notebook 镜像
使用下一节创建的 graphics-notebook
镜像。
c.DockerSpawner.image = 'graphics-notebook'
notebook 目录
设置暴露给用户的 notebook 目录。
本文的 notebook 镜像基于jupyter/docker-stacks 系列镜像构建,使用的用户名均为 jovyan
。
所以 notebook 目录可以设置为 '/home/jovyan/work'
。
import os
notebook_dir = os.environ.get('DOCKER_NOTEBOOK_DIR') or '/home/jovyan/work'
c.DockerSpawner.notebook_dir = notebook_dir
挂载
设置目录挂载。
有两种形式:
- volume 挂载:推荐将用户数据保存到单独的 volume 中。
- 目录绑定:推荐仅使用只读方式挂载
下面的代码中使用 volume 方式挂载 notebook 目录,并使用只读目录绑定方式挂载程序目录和数据目录。
c.DockerSpawner.volumes = {
'jupyterhub-user-{username}': notebook_dir,
"/home/wangdp/project/graphics/operation/system": {
"bind": "/srv/system",
"mode": "ro",
},
"/sstorage1": {
"bind": "/sstorage1",
"mode": "ro",
}
}
Notebook 镜像
基于 jupyter/base-notebook 构建新的镜像,安装 nwpc-data
和 nwpc-graphics
库,并安装绘图需要的 ncl 和 imagemagick 库。
设置环境变量 NWPC_GRAPHICS_CONFIG
。
FROM jupyter/base-notebook:latest
COPY lib /srv/lib
RUN cd /srv/lib/nwpc-data && \
python3 -m pip install . && \
cd /srv/lib/nwpc-graphics && \
python3 -m pip install .
RUN conda install -c conda-forge -y ncl imagemagick
ENV NWPC_GRAPHICS_CONFIG /srv/lib/nwpc-graphics/tool/docker/config/config.yaml
WORKDIR /srv
构建镜像,并命名为 graphics-notebook
。
sudo docker build \
--rm \
-t graphics-notebook \
.
运行
运行方法与前一篇文章一样。
sudo docker run \
--rm -it \
-v /var/run/docker.sock:/var/run/docker.sock \
--net jupyterhub \
--name jupyterhub \
-p 9500:8000 \
hub
使用 nwp
用户登录后,从 Portainer 中可以看到有新的容器被创建
同时有新的 volume 被创建
如果 volume 已存在,则会直接使用,这样就保证用户数据不会丢失。
参考
https://jhubdocs.readthedocs.io/en/latest/dockerspawner/README.html#configuration