docker 搭建 jupyter notebook远程环境

前言

之前的文章说了服务器怎么搭建jupyter环境:https://blog.csdn.net/Qwertyuiop2016/article/details/85137644

但是我发现,这样配置有点麻烦不说,换个机器又要重新来一遍,能不能来个一劳永逸的方法?那肯定是docker了

官方镜像

官方文档:https://jupyter-docker-stacks.readthedocs.io/en/latest/using/selecting.html

选择镜像

官方提供了几个镜像:

  1. jupyter/base-notebook
  2. jupyter/minimal-notebook
  3. jupyter/r-notebook
  4. jupyter/scipy-notebook
  5. jupyter/tensorflow-notebook
  6. jupyter/datascience-notebook
  7. jupyter/pyspark-notebook
  8. jupyter/all-spark-notebook

第一个为基础镜像,就是只包含基本的notebook功能。第二个在第一个的基础上安装了一些工具,具体装了啥可以看dockerfile。其他的就是安装了一些第三方Python库。我们自己搭建的话基本就是在第一个和第二个中选择

启动容器

docker命令就不细说了,请自行查阅:https://www.runoob.com/docker/docker-command-manual.html

  1. docker pull jupyter/base-notebook:latest 拉取镜像
  2. docker run --rm -p 8888:8888 jupyter/base-notebook:latest 运行镜像
Executing the command: jupyter notebook
[I 19:31:09.573 NotebookApp] Writing notebook server cookie secret to /home/jovyan/.local/share/jupyter/runtime/notebook_cookie_secret
[W 19:31:11.930 NotebookApp] WARNING: The notebook server is listening on all IP addresses and not using encryption. This is not recommended.
[I 19:31:12.085 NotebookApp] JupyterLab alpha preview extension loaded from /opt/conda/lib/python3.6/site-packages/jupyterlab
[I 19:31:12.086 NotebookApp] JupyterLab application directory is /opt/conda/share/jupyter/lab
[I 19:31:12.117 NotebookApp] Serving notebooks from local directory: /home/jovyan
[I 19:31:12.117 NotebookApp] 0 active kernels
[I 19:31:12.118 NotebookApp] The Jupyter Notebook is running at:
[I 19:31:12.119 NotebookApp] http://[all ip addresses on your system]:8888/?token=3b8dce890cb65570fb0d9c4a41ae067f7604873bd604f5ac
[I 19:31:12.120 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 19:31:12.122 NotebookApp]

    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://localhost:8888/?token=3b8dce890cb65570fb0d9c4a41ae067f7604873bd604f5ac

这只是测试一下,你可以浏览器访问一下最后一行格式的url,localhost换成服务器的ip,应该能正常访问,如果不能请开放服务器的防火墙和运营商的防火墙
3. 这样虽然能访问,但是我想将notebooks的根目录映射到本地。但是从上面的启动日志来看,默认的根目录在/home/jovyan,这个目录包含很多隐藏文件,映射时有些文件会报错,所以我们需要修改jupyter notebook的工作目录。
4. 修改设置参数的命令格式:docker run -p 8888:8888 jupyter/base-notebook start-notebook.sh --NotebookApp.password='sha1:74ba40f8a388:c913541b7ee99d15d5ed31d4226bf7838f83a50e'
就是在后面跟start-notebook.sh 然后在加上参数和值。

参数列表请看:https://jupyter-notebook.readthedocs.io/en/stable/config.html

挑几个我比较关心的参数:

  • NotebookApp.password:notebook访问密码
  • NotebookApp.allow_password_change:是否允许远程修改密码
  • NotebookApp.allow_remote_access:这个不知道是啥意思,反正我每次都加了
  • NotebookApp.open_browser:是否打开浏览器,这个在容器里默认就是False,所以可以不加
  • NotebookApp.notebook_dir:notebook工作目录

NotebookApp.password 后面不是跟的明文,需要运行下面两行Python代码设置之后,复制返回值
from notebook.auth import passwd
passwd()
5. 完整的docker命令

docker run -d \
	-p 8888:8888 \
    -v /var/jupyter:/home/jovyan/work \
    --name jupyter \
    jupyter/minimal-notebook:latest \
    start-notebook.sh \
    --NotebookApp.password='argon2:$argon2id$v=19$m=10240,t=10,p=8$zicxxxxxxxxxxxxxx4Q$+d1Sl9l+UvwRFc9CIPGPsg' \
    --NotebookApp.allow_password_change=False \
    --NotebookApp.allow_remote_access=True \
    --NotebookApp.open_browser=False \
    --NotebookApp.notebook_dir="/home/jovyan/work"
  1. 这里有个需要注意的,/home/jovyan/work目录是容器里的,而/var/jupyter是主机里的,需要你自己创建后修改所有者和所属组。当然,如果不想麻烦的话,直接在docker run -d 后面加上 --user root,它就会自动帮你修改。不修改的话,你会创建不了笔记,显示权限不足。
    mkdir /var/jupyter
    chown lighthouse:users /var/jupyter
    chmod 777 /var/jupyter 这一步应该是不需要的,不过设置了也没问题

增加插件和conda虚拟环境

在这里插入图片描述
默认只有前三个File、Running和Clusters,我们可以安装插件和conda虚拟环境

插件的话只需要安装jupyter_contrib_nbextensions这个包就行,容器已经内置了conda,所以只需要让jupyter支持conda虚拟环境就行,安装nb_conda包就行。还有一个包yapf也需要安装,好像是命令自动补全的,有点忘了。

进入容器的命令:docker exec -it -u root jupyter bash -u root 表示以root启动,默认是jovyan
进入之后执行:conda install --yes yapf nb_conda jupyter_contrib_nbextensions
重启容器后生效:docker restart jupyter

小bug

nb_conda一直有个bug没有修复

EnvironmentLocationNotFound: Not a conda environment: /opt/anaconda/envs/anaconda

解决方法:https://github.com/Anaconda-Platform/nb_conda/issues/66

简单来说就是把envmanager.py文件里的for env in info['envs']]修改为for env in info['envs'] if env != info['root_prefix']]

容器内这个文件的完整路径:/opt/conda/lib/python3.9/site-packages/nb_conda/envmanager.py

可以执行sed -i "s/info\['envs'\]\]/info['envs'] if env != info['root_prefix']]/g" /opt/conda/lib/python3.9/site-packages/nb_conda/envmanager.py这个命令替换

自定义镜像

上面启动容器之后还需要做一些操作,为什么不直接将这些操作打包成镜像呢,这样换一台机器也能直接启动,不需要修改任何东西

官方镜像的dockerfile文件:https://github.com/jupyter/docker-stacks

根据这些文件一眼就能看出minimal-notebook比base-notebook多了些什么,所以我们也根据base-notebook来修改我们的dockerfile。我去掉了他安装的git、vim等工具,如果你需要,可以自行加上。我其实就增加了后面两个RUN命令,第一个命令用来安装包,第二个用来修改envmanager.py文件。这里的mamba和conda是一样的,大概是conda的升级版

FROM jupyter/base-notebook

USER root

RUN apt-get update --yes && \
    apt-get install --yes --no-install-recommends \
    tzdata \
    openssh-client \
    inkscape \
    libsm6 \
    libxext-dev \
    libxrender1 \
    lmodern \
    netcat \
    texlive-xetex \
    texlive-fonts-recommended \
    texlive-plain-generic && \
    apt-get clean && rm -rf /var/lib/apt/lists/*

RUN mamba install --yes \
    yapf \
    nb_conda \
    jupyter_contrib_nbextensions && \
    mamba clean --all -f -y && \
    fix-permissions "${CONDA_DIR}" && \
    fix-permissions "/home/${NB_USER}"

RUN sed -i "s/info\['envs'\]\]/info['envs'] if env != info['root_prefix']]/g" /opt/conda/lib/python3.9/site-packages/nb_conda/envmanager.py

USER ${NB_UID}

将上面的内容保存为Dockerfile文件(无后缀名),接着在当前目录运行docker build -t kanade/jupyter:v1 . -t 后面是镜像名,随意指定(注意最后面有个小数点表示当前目录)。

启动的命令和上面的基本是一样的,只需要把jupyter/minimal-notebook:latest替换成kanade/jupyter:v1就行了

打包配置文件

上面创建的docker,还是需要在启动时指定参数,要不连配置参数也一起打包到镜像里

只需要在上面的dockerfile后面加

COPY jupyter_notebook_config.py /etc/jupyter/

USER root

# Prepare upgrade to JupyterLab V3.0 #1205
RUN sed -re "s/c.NotebookApp/c.ServerApp/g" \
    /etc/jupyter/jupyter_notebook_config.py > /etc/jupyter/jupyter_server_config.py && \
    fix-permissions /etc/jupyter/

USER ${NB_UID}

其中jupyter_notebook_config.py就是notebook的配置文件,在dockerfile同目录下创建这个文件,内容如下(记得修改下面的密码):

import os

c = get_config()  # noqa: F821
c.NotebookApp.ip = "0.0.0.0"
c.NotebookApp.port = 8888
c.NotebookApp.open_browser = False
c.NotebookApp.password = 'argon2:$argon2id$v=19$m=10240,t=10,p=8$zicg2xxxxxxxxxxx$+d1Sl9l+UvwRFc9CIPGPsg'
c.NotebookApp.allow_password_change = False 
c.NotebookApp.allow_remote_access = True
c.NotebookApp.notebook_dir="/home/jovyan/work"
# https://github.com/jupyter/notebook/issues/3130
c.FileContentsManager.delete_to_trash = False

if "NB_UMASK" in os.environ:
    os.umask(int(os.environ["NB_UMASK"], 8))

那么在构建镜像的时候就会替换镜像里的默认配置,启动时也不需要加什么配置了。另外,默认的配置文件里有https证书的相关配置,因为我不需要证书,用http就行了,所以直接删除了那部分。

启动命令:docker run -d -p 8888:8888 -v /var/jupyter:/home/jovyan/work --name jupyter kanade/jupyter:v1

保存

要想在其他机器上使用这个容器,有很多方法,比如将镜像存为文件docker save -o jupyter.tar kanade/jupyter:v1。或者注册一个阿里云账号,推送到阿里云仓库等

JupyterLab

只需在容器加一个参数-e JUPYTER_ENABLE_LAB=yes,这样启动的就是JupyterLab,默认的是jupyter notebook
docker run -p 1024:8888 --rm -e JUPYTER_ENABLE_LAB=yes --name jupyterlab jupyter/base-notebook
或者在后面增加 start.sh jupyter lab
docker run -p 1024:8888 --rm --name jupyterlab jupyter/base-notebook start.sh jupyter lab

经过测试发现,上面的两个参数,仅仅是修改了默认访问的是notebook还是jupyterlab。其实即使你启动的是notebook,依旧可以访问jupyterlab,只需要把路径上的tree改成lab即可

自动补全

在notebook中自动补全只需要启用hinterland这个插件就会有实时的代码提示,而在jupyterlab中需要安装额外的插件。

插件地址:https://github.com/krassowski/jupyterlab-lsp

安装扩展:conda install jupyterlab-lsp或者pip install jupyterlab-lsp

在这里插入图片描述

需要’jupyterlab>=3.0.0,<4.0.0a0 ',docker创建的jupyterlab应该是3.1,所以安装是没问题的。另外,这个只是主插件的库,还需要在网页上安装:Extension Manager(就是那个插件的图标,鼠标悬停可以显示文字)WARNING那一栏点击enable,并且搜索lsp,安装@krassowski/jupyterlab-lsp,最后一步就是安装Python的补全插件jedi-language-server,同样是pip或者conda都行。

如果想实时自动提示,Settings->Advanced Settings Editor->Code Completion 在右边的
User Preferences里的{}改成(不建议改左边的默认)

{
    "continuousHinting": true,
}

在这里插入图片描述

中文

安装jupyterlab-language-pack-zh-CN, conda、pip应该都行,安装完之后应该能看到下图的中文,切换即可,如果没有可以重启容器。
在这里插入图片描述

其他语言支持

在这里插入图片描述

C++

github地址:https://github.com/jupyter-xeus/xeus-cling

使用conda或者mamba安装即可mamba install xeus-cling -c conda-forge, 安装完成就能看到和运行了

JavaScript

github地址:https://github.com/n-riesco/ijavascript

运行下面两行就行了

npm install -g ijavascript
ijsinstall

Java

github地址:https://github.com/SpencerPark/IJava

Java比较麻烦,需要安装jdk9+

add-apt-repository ppa:openjdk-r/ppa
apt-get update
apt install openjdk-11-jdk

docker 里默认没有add-apt-repository,百度一下怎么安装吧

接着在 https://github.com/SpencerPark/IJava/releases 下载ijava的zip文件,解压之后运行 python install.py --sys-prefix即可安装成功了

在jupyter里导包有三种方式:

  1. 导入本地包: %jars 本地绝对路径。导入的包必须是jar格式文件,或者是目录(默认导入目录下的所有jar)
  2. maven导入,以okhttp为例:%maven com.squareup.okhttp3:okhttp:3.10.0
  3. xml文件形式导入:
%%loadFromPOM
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>3.10.0</version>
</dependency>

查看内核

jupyter kernelspec list 查看可用内核
jupyter kernelspec remove java 移除某个内核

打包

至于怎么将后面这些一起打包进镜像就不多说了,和之前的差不多。

在这里插入图片描述
打包完的镜像有点大,3.72G。怎么优化我暂时还不会,对docker仅仅是了解,边百度边使用。

猜你喜欢

转载自blog.csdn.net/Qwertyuiop2016/article/details/120439121