0%

Docker部署Jupyter

为了方便随时随地测试一些算法,做一些研究。笔者在自己的服务器上安装了jupyter-lab,这个是jupyter的下一代版本。但是因为不想搞乱自己服务器的环境,于是尝试寻找看看有没有jupyter的docker镜像,发现还真的有官方出的镜像。

官方出了很多镜像,根据不同的需求选择合适的镜像。本次搭建笔者选择了jupyter/datascience-notebook这个镜像,具体镜像列表参考:

https://jupyter-docker-stacks.readthedocs.io/en/latest/using/selecting.html

拉取镜像

1
docker pull jupyter/datascience-notebook

运行一个容器

1
docker run -p 8888:8888 jupyter/datascience-notebook
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
root@ubuntu:~# docker run -p 8888:8888 jupyter/datascience-notebook
Executing the command: jupyter notebook
[I 12:28:00.559 NotebookApp] Writing notebook server cookie secret to /home/jovyan/.local/share/jupyter/runtime/notebook_cookie_secret
[I 12:28:02.995 NotebookApp] JupyterLab extension loaded from /opt/conda/lib/python3.8/site-packages/jupyterlab
[I 12:28:02.996 NotebookApp] JupyterLab application directory is /opt/conda/share/jupyter/lab
[I 12:28:03.006 NotebookApp] Serving notebooks from local directory: /home/jovyan
[I 12:28:03.006 NotebookApp] Jupyter Notebook 6.1.5 is running at:
[I 12:28:03.007 NotebookApp] http://a0a0fecd00d5:8888/?token=2f725d16b757283384db037ff1707b590eca49d9ac037f3b
[I 12:28:03.007 NotebookApp] or http://127.0.0.1:8888/?token=2f725d16b757283384db037ff1707b590eca49d9ac037f3b
[I 12:28:03.007 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 12:28:03.019 NotebookApp]

To access the notebook, open this file in a browser:
file:///home/jovyan/.local/share/jupyter/runtime/nbserver-7-open.html
Or copy and paste one of these URLs:
http://a0a0fecd00d5:8888/?token=2f725d16b757283384db037ff1707b590eca49d9ac037f3b
or http://127.0.0.1:8888/?token=2f725d16b757283384db037ff1707b590eca49d9ac037f3b

访问你部署docker的那台主机,例如本次我部署在jupyter.local这台主机上,我们访问http://jupyter.local:8888会看到如下界面。

20201222203043

你可以使用token登录或使用token设置一个新密码。本次的token为2f725d16b757283384db037ff1707b590eca49d9ac037f3b

20201222203206

用token设置一个新密码然后登录。

20201222203257

这样就进来了。

但是这样我们的所有工作都在这个容器里,没有挂载外部的数据卷进来,当容器消失后我们的工作内容也将烟消云散。所以我们需要挂载外部的数据卷进来。

这里推荐使用docker-compose来启动容器,yaml格式的语法阅读非常清晰。

ubuntu 可以使用以下命令安装

1
apt install docker-compose -y

这里我们来看一个 docker compose 模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
version: "3.1"
services:
Jupyter:
image: jupyter/datascience-notebook:latest
tty: true
restart: always
container_name: jupyter
user: root
ports:
- "8888:8888"
volumes:
- "${PWD}/work:/home/jovyan/work"
environment:
- JUPYTER_ENABLE_LAB=yes
- GRANT_SUDO=yes
logging:
driver: "json-file"
options:
max-size: "100m"

在当前目录下新建一个work目录, 我们把这个目录挂载到容器里。
JUPYTER_ENABLE_LAB=yes启用jupyter-lab,这个是jupyter的下一代版本。

1
2
3
4
root@ubuntu:/home/naonao# mkdir work
root@ubuntu:/home/naonao# ls
work
root@ubuntu:/home/naonao#

例如我在/home/naonao这个目录下新建一个work文件夹,然后再本目录下创建一个docker-compose.yaml文件,复制上面的内容进去。

运行容器

1
docker-compose up
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
root@ubuntu:/home/naonao# nano docker-compose.yaml
root@ubuntu:/home/naonao# ls
docker-compose.yaml work
root@ubuntu:/home/naonao# docker-compose up
Creating network "naonao_default" with the default driver
Creating jupyter ... done
Attaching to jupyter
jupyter | Set username to: jovyan
jupyter | usermod: no changes
jupyter | Granting jovyan sudo access and appending /opt/conda/bin to sudo PATH
jupyter | Executing the command: jupyter lab
jupyter | [I 12:40:59.811 LabApp] Writing notebook server cookie secret to /home/jovyan/.local/share/jupyter/runtime/notebook_cookie_secret
jupyter | [I 12:41:00.953 LabApp] JupyterLab extension loaded from /opt/conda/lib/python3.8/site-packages/jupyterlab
jupyter | [I 12:41:00.954 LabApp] JupyterLab application directory is /opt/conda/share/jupyter/lab
jupyter | [I 12:41:00.957 LabApp] Serving notebooks from local directory: /home/jovyan
jupyter | [I 12:41:00.958 LabApp] Jupyter Notebook 6.1.5 is running at:
jupyter | [I 12:41:00.958 LabApp] http://051c0b8b860b:8888/?token=a37dc92a50b7b6f3fb0f01abfee6a374b5fb74d23a0a3114
jupyter | [I 12:41:00.958 LabApp] or http://127.0.0.1:8888/?token=a37dc92a50b7b6f3fb0f01abfee6a374b5fb74d23a0a3114
jupyter | [I 12:41:00.958 LabApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
jupyter | [C 12:41:00.963 LabApp]
jupyter |
jupyter | To access the notebook, open this file in a browser:
jupyter | file:///home/jovyan/.local/share/jupyter/runtime/nbserver-14-open.html
jupyter | Or copy and paste one of these URLs:
jupyter | http://051c0b8b860b:8888/?token=a37dc92a50b7b6f3fb0f01abfee6a374b5fb74d23a0a3114
jupyter | or http://127.0.0.1:8888/?token=a37dc92a50b7b6f3fb0f01abfee6a374b5fb74d23a0a3114

同刚才一样,你可以用token设置一个密码,或者也可以直接访问连接http://jupyter.local:8888/?token=a37dc92a50b7b6f3fb0f01abfee6a374b5fb74d23a0a3114,这里注意访问你部署docker的主机的地址,本例我部署在jupyter.local主机。我们将看到jupyer-lab的界面。

20201222204526

进入/work目录新建一个文件。

20201222204649

我的得到了一个Permission denied错误。

查阅资料发现

1
You must grant the within-container notebook user or group (NB_UID or NB_GID) write access to the host directory (e.g., sudo chown 1000 /some/host/folder/for/work).

https://jupyter-docker-stacks.readthedocs.io/en/latest/using/common.html

你必须允许容器的用户或组写你设置的这个目录

例如我挂载目录/home/naonao/work到容器里, 那么我需要更改这个目录的权限.chown 1000 /home/naonao/work

重启容器,问题解决。

20201222204942

1
2
3
4
root@ubuntu:/home/naonao# cd work
root@ubuntu:/home/naonao/work# ls
Untitled.ipynb
root@ubuntu:/home/naonao/work#

如果把它架设在公共云上,那么我们可以通过域名在任意位置访问到jupyter环境。

Nginx + SSL

通过Nginx反向代理并使用SSL加密HTTP

笔者用宝塔新建了一个静态网站,并设置了Let’s Encrpyt证书。
20201222205257

在华为云上部署docker,因为8888端口被占用,所以本次使用10000端口,在宝塔面板添加一个反向代理,当然你也可以自己配置Nginx。

20201222205721

完成单击配置文件

20201222210023

增加websocket

1
2
3
4
5
6
7
# websocket headers
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Scheme $scheme;

proxy_buffering off;

然后在点击左边目录的配置文件增加

1
2
3
4
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

20201222205825

保存。

访问https://jupyter.wudinaonao.com一切正常

20201222210506

可能遇到的问题

Python3 connecting

有时候通过Nginx反向代理会出现可以访问界面但是无法连接到python,这是因为没有配置websocket导致。

通常出现在这种情况下,用户通过HTTPS访问Nginx的反向代理。即

user —https—> nginx —http—> docker

https://jupyter-docker-stacks.readthedocs.io/en/latest/using/selecting.html

https://jupyterhub.readthedocs.io/en/stable/reference/config-proxy.html