配置 jupyterhub


目标:

注意:我这里图省事下面全程使用 root 操作,如果想不以 root 启动,见官方文档 Run JupyterHub without root privileges using sudo,但是配置过程会复杂很多。

如果不使用多用户或不使用 conda,conda install 改为 pip3 install,并忽略 conda 环境创建步骤。


2019.1.3: 官方的 docker 镜像 docker jupyerhub

1. jupyterhub prerequisites

1.1 python 以及 jupyter 安装

此处采用 conda 安装 python,并实现目标的 1 和 2,conda 相关见 xxxxxxxx

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

1.2 nodejs 安装

nodejsnpm 的安装:

yum install -y npm

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

npm install -g n  # 安装 nodejs 版本管理工具
n stable  # 安装 nodejs 最新稳定版本
npm install -g npm  # 安装 npm 最新稳定版本

更改源:

npm config set registry https://registry.npm.taobao.org

2. 安装 jupyterhub

npm install -g configurable-http-proxy
conda install jupyterhub

3. 配置

3.1 hub 账户

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

useradd -m youracount  # 新建你的用户
passwd youracount  # 设置密码

新建用户后 一定要检查家目录权限,保证目录 youracount 有读写权限。否则账户登陆后会有权限错误。

如果不是多用户或不使用 conda,下面 conda 相关的步骤请忽略。

此处再配置此用户的虚拟环境,名称为 py37:

su youracount  # 切换到此用户

cd ~

conda create --prefix $HOME/.conda/envs/py37  # 创建conda 虚拟环境
conda init bash

echo "conda activate py37" >> .bashrc

安装 nb_conda,这样 jupyterhub 可以自动发现用户的 kernel。

conda install nb_conda

3.2 hub 配置

  1. 生成配置文件到 /etc/jupyterhub:
    mkdir /etc/jupyterhub && cd /etc/jupyterhub
    jupyterhub --generate-config
    
  2. 创建文件夹以存储 jupyterhub 的 cookie, sqlite 文件:
    mkdir /srv/jupyterhub
    
    vim jupyterhub_config.py
    
  3. 我的配置文件内容:
    # cookie file and sqlite file
    c.JupyterHub.cookie_secret_file = '/srv/jupyterhub/jupyterhub_cookie_secret'
    c.JupyterHub.db_url = '/srv/jupyterhub/jupyterhub.sqlite'
    
    # Jupyterhub general setting
    c.JupyterHub.ip = '0.0.0.0'
    c.JupyterHub.port = 80
    c.PAMAuthenticator.encoding = 'utf8'
    
    c.Spawner.notebook_dir = '~'
    c.Spawner.default_url = '/lab'  # 默认启动jupyterlab
    
    # 当前登录用户执行操作,重要!否则会有权限问题
    c.LocalProcessSpawner.shell_cmd = ["bash", "-l", "-c"]
    
    # 可配置非当前环境的 kernel
    c.Spawner.args = ["--KernelSpecManager.ensure_native_kernel=False"]
    
    # 账户设置
    #c.Authenticator.whitelist = {'jupyter'}  # 白名单
    c.Authenticator.admin_users = {'jupyter'}  # 管理员用户
    
    # 用户不存在时,创建为 linux 用户
    c.PAMAuthenticator.open_sessions = False  # centos 需要关闭,否则会有 PAM 认证错误
    c.LocalAuthenticator.create_system_users = True
    c.PAMAuthenticator.add_user_cmd = ['adduser', '-m']  # 创建用户的命令
    #c.Authenticator.delete_invalid_users = True
    
  4. 为 hub 中新增的 linux 用户设置默认密码:

    修改 /path/to/site-packages/jupyterhub 下的 auth.py 文件,在文件头部导包:

    import crypt
    

    在类 LocalAuthenticator 的方法 add_system_usercmd += [name] 之前一行添加一行,如下:

    cmd += ['-p', crypt.crypt(name, 'salt')]  # default passwd is username
    

    这样新建的 Linux 用户才会拥有密码,才能登录,否则无法通过 PAM 认证。

  5. 测试:

    jupyterhub -f /etc/jupyterhub/jupyterhub_config.py
    

    确认 juyterhub 启动无错误信息再配置反代理。

上面这样配置的 jupyterhub 需要以管理员启动。

3.5 nginx 反代理

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

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

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

  3. nginx 安装/配置不在重复,见xxx

  4. 新建 jupyterhub 的代理配置文件:

    # 在 conf.d 下创建配置文件
    touch /etc/nginx/conf.d/jupyterhub.conf
    
    # 编辑文件配置如下信息
    vim /etc/nginx/sites-available/jupyterhub.conf
    
  5. 配置文件:
    # top-level http config for websocket headers
    # If Upgrade is defined, Connection = upgrade
    # If Upgrade is empty, Connection = close
    map http_upgradeconnection_upgrade {
       default upgrade;
       ''      close;
    }
    
    # HTTP server to redirect all 80 traffic to SSL/HTTPS
    server {
       listen 80;
       server_name jp.brothereye.cn;
       # Tell all requests to port 80 to be 302 redirected to HTTPS
       return 302 https://hostrequest_uri;
    }
    
    # HTTPS server to handle JupyterHub
    server {
       listen 443 ssl;
    
       server_name jp.brothereye.cn;
    
       access_log /var/log/nginx/jp.access.log;
       error_log /var/log/nginx/jp.error.log;
    
       ssl_certificate cert/your.pem;  #自己证书文件, pem。
       ssl_certificate_key cert/your.key;  #自己证书文件, key
       ssl_session_timeout 5m;
       ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
       ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
       ssl_prefer_server_ciphers on;
    
       add_header Strict-Transport-Security max-age=15768000;
    
       # Managing literal requests to the JupyterHub front end
       location / {
           proxy_pass http://127.0.0.1:8000;
           proxy_set_header X-Real-IP remote_addr;
           proxy_set_header Hosthost;
           proxy_set_header X-Forwarded-For proxy_add_x_forwarded_for;
    
           # websocket headers
           proxy_set_header Upgradehttp_upgrade;
           proxy_set_header Connection $connection_upgrade;
       }
    
       # Managing requests to verify letsencrypt host
       location ~ /.well-known {
           allow all;
       }
    }
    

4. 启动 jupyterhub

这里使用 supervisor 来启动/停止 jupyterhub,supervisor 常用配置见: linux进程监管工具Supervisor

5. 错误总结

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

  • 如果做了上面的工作后发现配置任然没有生效,试试删除 /srv/jupyterhub 下的 cookie 和 sqlite 删除,如 cd /srv/jupyterhub && rm jupyterhub_cookie_secret jupyterhub.sqlite
  • 登陆 jupyterhub 后无法新建文件,网页的窗口说Path不存在,但查看终端会发现错误其实是: Permission denied,原因是当前登录的用户对当前文件夹无读写权限;
  • 总结:
    1. 检查 jupyterhub 配置;
    2. 检查 nginx 反代理配置,确认端口/ip统一;
    3. 检查域名解析;
    4. 检查 jupyterhub 账户权限。
评论
  • 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或者百度就有。

发表评论 说点什么