Docker实现Python的Jupyterhub远程开发环境集成

python可以有多种编程环境,notebook简单好用,基本代码块的编写调试是不错的。如果能将整个环境打包成docker容器,并部署成远程多用户安全连接就更好了,实现这个过程克服了不少问题,这里记录一下基本实现方法。

基本目的:

1、全部docker安装,这样所有组件与本地系统隔离,不容易搞乱操作系统而且可以移植、保存,实现一次部署分发使用。

2、用jupyterhub实现多用户远程外网使用。

3、用系统反向代理实现https安全连接。

实现方法:

1、docker安装一个有linux环境的基础镜像,并完成基础配置

linux的一般发行版都可以,最好已经带了python环境,如果没有python自己安装。基本步骤是:

1.1 拉取一个有linux环境的镜像。

1.2 按要求启动容器。

1.3 从终端进行容器内部,update linux操作系统到最新列表,添加系统用户并设置密码,以后notebook就用这些系统用户帐户登录。

1.4 在容器内安装python、安装pip(或者conda)。

2、docker容器中安装notebook

2.1 pip3 install jupyterhub安装jupyterhub服务器,这一步要做一些配置,按网上教程。配置以下几项就可以了。

c.JupyterHub.ip = '172.17.0.***'
c.JupyterHub.port = ****
c.JupyterHub.statsd_prefix = 'jupyterhub'
    
# 白名单用户
c.Authenticator.whitelist ={'user_name_1','user_name_2','user_name_3'}

因为安装在docker中,这里的ip地址要填容器内部真实ip,如果不清楚可终端进入容器内部,用ifconfig查看,如果系统提示未找到命令,可以先安装net-tools工具,因为容器都是极简系统有可能没有集成网络工具。

注:系统运行很长一段时间后进行了Docker版本的升级,再次运行容器时发现JupyterHub无法运行,在Supervisor工具的管理下反复重启,多处查看都不清楚原因,认为可能是Docker升级造成容器不兼容,准备重装该容器,再读这篇文章,“这里的ip地址要填容器内部真实ip”,想到系统更新可能造成内部ip变化,进入系统查看果然如此,修改配置文件中的参数,容器立刻稳定运行。

2.2 pip3 install jupyter安装notebook服务器。如果系统提示缺少依赖,一样pip install。如何不想启动本地的notebook编辑器,则notebook可以不配置。

3、退出容器,并停止容器运行,用容器管理工具将c.JupyterHub.ip指定的端口映射到宿主机的本地端,这一步可以提前在启动基础镜像时就映射好,有可能有些系统容器运行后不好再添加端口。

4、再次运行容器,进入容器,启动notebook服务。

cd 到jupyterhub配置文件目录,输入

nohup jupyterhub > jupyterhub.log & 让服务后台运行

打开浏览器输入ip:port验证系统是否真正已部署好,这里有可能会有问题,按网上教程应该都能解决。

5、利用宿主机的nginx反向代理实现SSL安全连接

5.1 准备需要SSL连接的域名和证书,按网上教程自行注册购买,都有免费的,一样好用,如果已有就没问题了。

5.2 宿主机安装nginx服务器,配置好wss,将jupyterhub容器的http连接配置成通过https反向代理。按通用配置就可以,不用考虑jupyterhub的特殊性,这是docker安装jupyterhub的一大优点,如果在主机上直接安装jupyterhub就必须按官网要求对nginx的配置进行修改,非常麻烦。

6、几点提醒:

6.1 容器内部相当于一个独立的操作系统环境,安装过程中缺少组件可以直接安装,python环境库比较多,必须满足依赖要求。

6.2 安装了pip3后,最好装一下conda,有极少数软件只有conda可以装。

6.3 基本安装完成后先局域网调试通过,确保运行常,如何连接有问题建议重新安装jupyter

6.4 用命令让jupyterhub后台运行,这样不会因为终端退出服务也跟着退出,用ps -a 命令检查进程是否真正运行,如果命令不能挂起可先回车再查看,不行再次运行挂起命令。少数时候因内部端口冲突会造成挂不起来,但每次运行挂起命令会用不同的端口,这样就可以避开冲突了。

6.5 在内网可以正常连接jupyterhub的情况下,用域名可以登入jupyterhub但显示无法连接python内核是因为nginx配置中没有正确设置好websocket。

6.6 最好在开始安装阶段将linux和pip的源改成国内的,否则有些安装可能无法进行下去。

6.7 现在可参考资料都要求安装anaconda配置虚拟环境,本文没有涉及,不同系统是否有不同没有更多的测试。

Jupyterhub登录后显示 500内部服务错误

juoyterhub安装后可以登录,其它各项功能正常,但notebook启动不了,显示500:内部服务错误。

尝试了各种方法,删除jupyterhub重装,删除jupyter重装,甚至删除与jupyter相关的所有目录、文件,均没有效果。

再仔细查看登录时jupyterhub的反馈信息,发现还有一个目录没有动过,nbconvert,全部删除,再重新安装,再次登录正常,问题解决。

500错误原因复杂,我产生这个问题很可能是先安装配置过本地的jupyter-notebook服务器,使nbconvert生成了本地连接,再安装jupyterhub时仍然调用旧的配置,自然无法运行,踩过的坑供大家参考。

近日第二次安装Jupyterhub,再次遇到500问题,上次碰运气解决问题,这次想真正搞清楚原因,并且这次尝试了多用户同时登录,在第一个用户登录后其他用户无法登录或登录后打不开python文件。

1、从网上调研该问题的解决方案

有关该问题的文章不多,大概几种认识,第一是认为安装notebook在先,生成/.jupyter文件,造成后面启动jupyterhub时读取老文件出现错误。第二是认为jupyterhub的设置文件对用户的身份认证和系统防火墙问题。

以上方案在我这里都不起作用,都是一种猜测,并没有真正搞清问题的根本原因。

2、自己动手调试

2.1 第一个用户登录时就出现500错误,采取前述办法,删除nbconvert文件夹,没有出现以前的结果,仍然无法登录。

调试信息显示 permissionERR 13 *******conf.json 表明jupyterhub不能正常处理该文件,打开所在目录发现在nbconvert目录下根本没有该文件。将以前安装的系统中的文件拷贝覆盖当前文件夹,成功登入,并能正常运行python程序。

2.2 第二个用户无法登入,只有第一个用户退出,第二个用户才能登录,并且登录后仍然无法打开python文件,用2.1的方法覆盖文件,仍然不起作用,并且系统没有permissionERR 13错误提示,只提示打开singlenotebookapp失败。

以上表明,2.1没有真正解决问题,并且当前系统只能单用户使用,根本不是多用户环境。从各种现象考虑,出现这些问题应该还是身份认证存在错误。

以第二个用户身份进入终端,在其中启动jupyterhub并尝试浏览器登录,这里系统再次出现permission ERR 13和runtime错误提示,即该用户无权执行相关文件,这算是该软件的一个bug吧。

对相关文件进行 chmod -R 777,退出普通用户环境,以root身份启动jupyterhub,多用户正常运行,问题解决。

普通用户要使用jupyterhub必须要有自己的主目录并配置在config文件中,有权读取配置文件,且第一次运行时要正确生成身份认证信息,否则均不能正常运行。