配置 jupyterhub


jupyterhub 相比 jupyter notebook 或者 jupyterlab 的优点支持多用户认证,我的服务器上次配置了 jupyterlab(链接: 配置远程 jupyterlab)但是没有用户认证,放在服务器上很容易被别人扫描到端口号进行破坏,所以这次配置好 jupyterhub 就可以让其一直保持在后台啦。

官方文档JupyterHub Docs 1.0.0

配置 jupyterhub 并使用 apache2 反代理到二级域名下,这里多说一句:推荐使用 nginx 反代理,它比较轻量,我由于博客配置在 apache2 下,也懒得再更换了。反代理官方文档: Using a reverse proxy

注意:我的服务器登陆后默认就是管理员,所以下面过程都是在管理员root身份下做的,如果当前用户不是管理员那会出现乱七八糟的问题,如果想不以 root 启动,见官方文档 Run JupyterHub without root privileges using sudo,但是难度较大非常复杂,并不推荐更改,就使用 root 身份省事,安全保护的话设置 jupyterhub 账户的权限就好了。


2019.1.3: 推荐使用docker,它里面有非常多配置好的镜像。docker jupyerhub

1. jupyterhub prerequisites

1.1 python 以及 jupyter 安装

前篇 Ubuntu 16.04 LTS 安装Python 3.6中有安装过程。以及 pip 的安装与更新,更换 pip 源在 标签: install-python 都有所记录。

jupyter 相关安装很简单 pip3 install 就好了。

1.2 nodejs 安装

nodejsnpm 的安装:

apt install nodejs-legacy
apt install npm

更新(推荐更新到新版,apt 安装的版本太旧,会导致很多错误):

npm install -g n  # 安装
n stable  # 更新 nodejs
npm install -g npm

2. 安装 jupyterhub

npm install -g configurable-http-proxy
python3 -m pip install jupyterhub

3. 配置

3.1 生成配置文件

/etc/jupyterhub 下面生成配置文件 jupyterhub_config.py

mkdir -p /etc/jupyterhub && cd /etc/jupyterhub
jupyterhub --generate-config

3.2 配置启动 jupyterlab

我比较喜欢使用 jupyterlab,所以配置启动为 lab。配置文件见后。

插件安装:

jupyter labextension install @jupyterlab/hub-extension
jupyter labextension install jupyterlab_bokeh

3.3 hub 登陆账户

先在 linux 下新建用户,后续配置文件中会用此登陆账户

useradd -m youracount  # 新建你的用户
passwd youracount  # 设置密码
mkdir /home/youracount/notebooks  # notebook保存的路径

新建用户后一定要检查 youracount目录和其下的notebooks目录权限,保证目录拥护者是 youracount 和 读写权限。如果不正确导致后面登陆后无法读写等错误。安全防护的话,给这个用户降权限就好了,不允许其读写家目录之外的文件。

3.4 hub 配置文件

配置文件的解释注释在配置文件的内容里,分开解释的话内容太长,所以此文没有分开解释。可以直接粘贴到 jupyterhub_config.py 最后面,但建议阅读下下面配置。

import os
file_path = os.path.dirname(os.path.abspath(__file__))


# db
c.JupyterHub.db_url = os.path.join(file_path, 'jupyterhub.sqlite')


# Jupyterhub setting
c.JupyterHub.ip = '127.0.0.1'  # 远程访问
c.JupyterHub.port = 8000
c.PAMAuthenticator.encoding = 'utf8'  # web编码。
c.Spawner.notebook_dir = '~/notebooks'

c.Spawner.default_url = '/lab'  # 启动jupyterlab
c.Spawner.cmd = ['jupyter-labhub']  # 启动jupyterlab
# 如果要启动 jupyter notebook,就去掉上面两条并取消注释下面这条。
#c.Spawner.cmd = ['jupyterhub-singleuser']


# whitelist
c.Authenticator.whitelist = {'youracount'}  # 白名单
c.Authenticator.admin_users = {'youracount'}  # 管理员用户
c.LocalAuthenticator.create_system_users = True  # 白名单里的账户在系统里不存在的话就会自动在系统里新建这些用户


# Jupyterhub service setting
c.JupyterHub.spawner_class = 'sudospawner.SudoSpawner'

3.5 Apache2 反代理

我的服务器早期安装的是apache,后来转到nginx了,nginx的反代理官方文档中也有。

参考 jupyterhub 官方链接: Using a reverse proxy,配置文件建议去这个官方链接复制。

  1. 二级域名申请及解析。我的域名是阿里云申请的,其可以免费开二级域名,解析的话主机记录填写二级域名就行了,其他设置同一级域名。例如我的二级域名是: jh.brothereye.cn,(apache2 配置中用此作为例子)

  2. SSL 证书申请,阿里云可以申请免费的 SSL。申请后下载证书放到 /etc/apache2/cert/nb 下,假设分别为: 222_yourhost_chain.crt222_yourhost_public.crt222_yourhost.key

  3. Apache2 安装:

    apt-get install apache2
    
  4. Apache2 使能反代理、SSL 模块:
    a2enmod ssl rewrite proxy proxy_http proxy_wstunnel
    
  5. Apache2 配置 1 (80端口),新建文件 /etc/apache2/sites-enabled/notebook.conf,写入下面内容(替换自己二级域名):
    <VirtualHost localhost:80>
    
       ServerAdmin webmaster@localhost
       ServerName jh.brothereye.cn
    
       Redirect / https://jh.brothereye.cn/
    
       ErrorLog {APACHE_LOG_DIR}/error_notebook.log
       CustomLog{APACHE_LOG_DIR}/access__notebook.log combined
    
    </VirtualHost>
    
  6. Apache2 配置 2 (443端口),新建文件 /etc/apache2/sites-enabled/notebook_ssl.conf,写入下面内容(替换自己二级域名, 以及证书路径):
    <IfModule mod_ssl.c>
       <VirtualHost _default_:443>
    
           ServerAdmin webmaster@localhost
           ServerName jh.brothereye.cn:443
    
           ErrorLog {APACHE_LOG_DIR}/error_notebook.log
           CustomLog{APACHE_LOG_DIR}/access_notebook.log combined
    
           SSLEngine on
           SSLCertificateFile cert/nb/222_yourhost_public.crt
           SSLCertificateKeyFile cert/nb/222_yourhost.key
           SSLCertificateChainFile cert/nb/222_yourhost_chain.crt
    
           # Use RewriteEngine to handle websocket connection upgrades
           RewriteEngine On
           RewriteCond %{HTTP:Connection} Upgrade [NC]
           RewriteCond %{HTTP:Upgrade} websocket [NC]
           RewriteRule /(.*) ws://127.0.0.1:8000/$1 [P,L]
    
           <Location "/">
               # preserve Host header to avoid cross-origin problems
               ProxyPreserveHost on
               # proxy to JupyterHub
               ProxyPass         http://127.0.0.1:8000/
               ProxyPassReverse  http://127.0.0.1:8000/
           </Location>
       </VirtualHost>
    </IfModule>
    
  7. 启动 apache2: /etc/init.d/apache2 restart仅仅启动apache2是无法访问的,还要启动 jupyterhub

4. 启动 jupyterhub

上面全部完成后即可启动。

jupyterhub -f /etc/jupyterhub/jupyterhub_config.py

这样浏览器就可以访问 jh.brothereye.cn,来使用 jupyterhub了。如果浏览器不能正常访问,检查 jupyterhub 启动窗口的输出信息。

实际使用时使用需要后台运行此会话,所以我这里使用tmux,详细安装及配置见 终端复用tmux配置及使用,脚本启动文件创建为:

touch jh
chmod +x jh
vim jh

启动文件写入以下内容:

#!/bin/bash
# jl - start jupyterhub in tmux

sess_name="jupyterhub"

export DISABLE_AUTO_TITLE="true"

tmux has-session -t sess_name
if [? = 0 ];then
    echo sess_name "already exist. attaching..."
    tmux attach-session -tsess_name
    # exit
else
    echo sess_name "doesn't exist. creating..."
    tmux new -d -ssess_name -n home
    tmux send-keys -t $sess_name:1 "jupyterhub -f /etc/jupyterhub/jupyterhub_config.py" Enter
fi

运行

./jh

5. 错误总结

我遇到的错误我在这里总结下:

  • 启动 jupyterhub 后发现配置没有生效(配置信息会在启动时显示出来,比如端口号等等)。如果发现没有生效原因可能是 jupyterhub 启动时所在文件夹没有配置文件(它认定的配置文件在启动目录下,而 ssh 登陆后会在当前用户的家目录下,家目录下显然没有!),这时解决方案有两个:一是启动时加上配置文件路径(见 #4 )。二是移动到那个目录下再启动(经测试,给配置文件建立软链也行不通)。
  • 如果做了上面的工作后发现配置任然没有生效,那去把 /etc/jupyterhub 下的两个缓存文件删除(建议每次更改配置后都删去)。rm jupyterhub_cookie_secret jupyterhub.sqlite
  • 不要忘记开启自己服务器安全组的入出规则,添加对应端口号到入规则。我之前有一篇里详细记录了阿里云入规则的设置过程
  • 如果配置过程和文件都是按照这篇做的但是远程无法访问,比如浏览器提示 ERR_EMPTY_RESPONSE ,这时访问 https 的试试。浏览器提示 ERR_CONNECTION_REFUSED等信息的话表明服务器没有成功开启对应端口的服务。
  • 登陆 jupyterhub 后无法新建文件,网页的窗口说Path不存在,但查看终端会发现错误其实是: Permission denied,我的解决方法是把对应用户的文件夹下权限设置好,文件夹拥护者以及其读写执行权限。我在 #3.4 里提到过。
评论
  • jupyter_error

    您好,我依照您的安裝步驟,也新增了一個使用者 "youraccount"修改了config檔 c.Authenticator.whitelist = {'youracount'} # 白名单 c.Authenticator.admin_users = {'youracount'} # 管理员 但是當我使用root啟動jupyterhub後,以youracount登入,仍然出現錯誤 500 : Internal Server Error Spawner failed to start [status=1]. The logs for youracount may contain details. You can try restarting your server from the home page. 請問一下,這個問題應該怎麼解決,謝謝。

    • em...我也不知道,你可以看看官方的错误汇总。如果还无法解决那可能是上面sudospawner的问题,你再看看我最上面放的那个链接,他的博客里详细记录了权限问题。我的所有配置都是以root身份执行的,如果你的不是root下配置的可能就需要配置sudospawner.

    • 其实自己也没必要在把过程走一遍,推荐你试试docker,它下面有很多配置好的python甚至是jupyterhub。docker的使用教程很多的,google或者百度就有。

发表评论 说点什么