1. 概要
(1年くらい前の自分用メモからの転載なので最新環境では上手く行かないところもあるかもしれません。ご容赦を!)
Python venvを利用したJupyterHubの構築です。なぜJupyterHubかって? 会社では計算資源が比較的潤沢なUbuntuマシン上に複数人で利用するJupyter環境が欲しかったし、自宅では常時動いているRaspberry Pi4 8GB上でJupyterHub動いていればWindowsからでもChromebookからでもいつでも作業ができるから。
IPythonだけでなく、SageMath(これがメインユース)、Wolfram Engineなんかを動かします。
JupyterHubの基本カーネル(JupyterLab)だけのminimalな環境が欲しいので、Anacondaは使わずにPython pipによるセットアップを実施します。基本はJupyterHubの公式手順に従いますが、venvの準備やnpmの準備について少し詳しく記載します。
手順は以下の通り。
- JupyterHub用Python venv環境のセットアップ
- Node.jsのセットアップ
- JupyterHubのインストール
- JupyterHubの初期設定
- SystemdへのJupyterHubサービスの登録(オプション)
以降の手順は Ubuntu, Debianを対象に書いていますが、aptなどのインストールコマンドが異なるだけで、その他のLinuxに限らずFreeBSDなどでも基本的な流れは同じ です。
尚、最近ならばDockerでJupyterHubを構築する方が便利そうな気もしますが、
- 複数ユーザーの管理そのもの
- 複数ユーザーのデータ置き場所(Samba等のアクセシビリティ)
- JupyterHubコンテナ外のJupyter Kernelの扱い
をきちんと設計・運用するのが面倒(コンテナの嫌な所だわ…)だったりして見送ってます。一方、Jupyter Kernel自体にはDockerコンテナが時として便利だったりするのです。
2. JupyterHub用Python venv環境のセットアップ
venv環境について、詳しくは公式の説明をご一読ください。要はシステムにインストール済みのPython環境は汚さずに閉じた場所にPythonパッケージをインストールする環境を与えるのがvenvです。
ここでは、システム全体で利用するローカル環境(root権限ディレクトリ)にvenvを構築します。
sudo mkdir -p /opt/local/python # /opt/local/pythonディレクトリを作成
sudo python3 -m venv /opt/local/python/ # 作成したディレクトリにvenv環境を作成
cd /opt/local/python/bin
sudo ./pip3 install -U pip setuptools wheel # venv環境で利用するpip等を最新のものにVer. UP
以上でvenv環境は完成。
3. Node.jsのセットアップ(JupyterHubの依存パッケージ)
JupyterHubはユーザーのログインを受け付けるプロキシをNode.js(configurable-http-proxy)に頼っているので、Node.jsをセットアップする必要があります。ここをきちんとしておかないと運用後に面倒なトラブルになりやすい。
結論を言えば、OS標準(Linuxディストリビューションの標準提供パッケージ)のNode.jsは使わない方がいい! なぜならば、バージョンが古い(最新のJupyterHubが対応していない)ことが多いから。
したがって、どうしてもOS標準のNode.jsでないと困るという人は頑張ってもらうしかないわけですが、特にこだわりがない人はNodeSource Node.js Binary Distributionsにしたがって、Node.js公式が用意してくれているバイナリを利用しましょう。
UbuntuにNode.js 18系(LTS)をインストールしたい場合:
sudo apt install curl # curlがまだインストールされていない人はまずはこれを実行
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - &&\
sudo apt install -y nodejs
以上で、最低限の準備が完了しました。続いてJupyterHubをインストールします。
4. JupyterHubのインストール
4.1. configurable-http-proxyのインストール
Node package managerからJupyterHubの依存パッケージであるconfigurable-http-proxyをインストールします。
sudo npm install -g configurable-http-proxy
4.2. JupyterHubのインストール
pipコマンドでJupyterHubをインストールします。ただしpipコマンドは先ほど構築したvenv環境のものを利用することに注意します。
# JupyterHub単体 + 基本カーネル(JupyterLab)
sudo /opt/local/python/bin/pip3 install jupyterlab jupyterhub
# 他に必要なものがある場合はここでインストールする。例えば以下のような感じ
sudo /opt/local/python/bin/pip3 install pandas matplotlib plotly
以上でインストール自体は完了です。続いて初期設定に移ります。
5. JupyterHubの初期設定
5.1. コンフィグファイルの生成
作成したvenv環境下にJupyterHubのコンフィグファイルを生成します。
cd /opt/local/python # venv環境に移動
sudo mkdir -p etc/jupyterhub # jupyterhubディレクトリを作成する
cd etc/jupyterhub # jupyterhubディレクトリに移動する
sudo /opt/local/python/bin/jupyterhub --generate-config # JupyterHubコンフィグファイル(jupyterhub_config.py)を生成する。
以上により、/opt/local/python/etc/jupyterhub 配下に jupyterhub_config.py が生成されます。
5.2. 自己署名証明書の準備(オプション)
JupyterHubをHTTPSで運用する場合は、SSLサーバー証明書が必要になります。HTTPSが不要な場合(HTTP接続の運用で良い場合)は本項はスキップできます。
最近では無料でSSLサーバ証明書を扱う色々な方法がありますが、閉じたLAN環境での運用というのもあって旧来の「自己署名証明書(オレオレ証明書)」で運用します。(ブラウザでアクセスすると警告が出るアレです)
外部に公開するなど、内輪で閉じた世界での利用でない場合はきちんとしたSSLサーバー証明書を準備しましょう。
# ユーザー権限で証明書は作成できます。OpenSSLで証明書を作成。
# 途中で色々聞かれます。都度入力します。
openssl genrsa 2048 > jupyterhub.key
openssl req -new -key jupyterhub.key > jupyterhub.csr
openssl x509 -req -days 3650 -signkey jupyterhub.key < jupyterhub.csr > jupyterhub.cert
作成した証明書 "jupyterhub.key", "jupyterhub.cert" をJupyterHub設定ディレクトリに配置します。
sudo mkdir -p /opt/local/python/etc/jupyterhub/keys
sudo cp jupyterhub.key /opt/local/python/etc/jupyterhub/keys/
sudo cp jupyterhub.cert /opt/local/python/etc/jupyterhub/keys/
5.3. コンフィグファイルの調整
生成したコンフィグファイルを自身の環境に合わせて調整します。私の環境では以下のパラメータをコメントから外して設定します。
# ローカルIPアドレスをJupyterHubに使用する
c.JupyterHub.ip = '0.0.0.0'
# 以下の2つはHTTPSアクセス用(設定しない場合は自動的にHTTPアクセスになったはずだが…)
c.JupyterHub.ssl_cert = '/opt/local/python/etc/jupyterhub/keys/jupyterhub.cert'
c.JupyterHub.ssl_key = '/opt/local/python/etc/jupyterhub/keys/jupyterhub.key'
# venv環境にPATHが通っていない場合は、Spawnerに実行パスを教える
c.Spawner.cmd = ['/opt/local/python/bin/jupyterhub-singleuser']
# JupyterLabを使うように指定する
c.Spawner.default_url = '/lab'
# JupyterHubで利用する個人ディレクトリのパスを指定する
c.Spawner.notebook_dir = '~/notebook'
さらに初期ユーザーを設定します。(私の場合は利用者が少ないのでGUIは使わずに以下ファイルに全ユーザーを列挙する運用です)
# 管理者アカウントを設定。OSのユーザーアカウントで指定する。
c.Authenticator.admin_users = {'yksantaro'}
# 利用者アカウントを設定。OSのユーザーアカウントで指定する。
c.Authenticator.allowed_users = {'yksantaro'}
以上で準備完了です。起動して上手く動くか確認します。
5.4. 起動確認
まず最初にユーザーのホームディレクトリにc.Spawner.notebook_dirに設定したディレクトリ(上記設定では ~/notebook)が存在するか確認します。存在しない場合はJupyterHubからのログイン時にエラー停止してしまうので作成しておきます。
cd # ユーザーのホームディレクトリに移動
mkdir notebook # notebookディレクトリを作成しておく
JupyterHubを起動します。
cd /opt/local/python/etc/jupyterhub # コンフィグファイルの配置ディレクトリに移動
sudo /opt/local/python/bin/jupyterhub # JupyterHub起動
コンソールにメッセージがずらずらと出力されます。
Webブラウザから https://{JupyterHubのIPアドレス}:8000/ (あるいは http://{JupyterHubのIPアドレス}:8000/) にアクセスしてログインします。正常にログインできれば設定は上手く行きました。
もし、うまく動いていない場合はコンソールに出力されるメッセージを手寧に確認します。大抵はPythonのエラーメッセージが出ていると思います。メッセージを手掛かりにトラブルシュートします。
configurable-http-proxyやSpawner周辺でエラーとなることが多い。あとはPermission関係とか…
動作確認ができれば、コンソールにてCtrl-Cを押下してJupyterHubを停止します。
6. SystemdへのJupyterHubサービスの登録(オプション)
多くの場合JupyterHubは常時動いているサーバー扱いとなるでしょうから、Systemdにサービス登録しておくと便利です。Linuxの起動と同時にJupyterHubも起動するように設定します。
6.1. Systemdユニットファイル作成・リンク作成
先ほどのvenv環境内にSystemdユニットファイルを作成します。
sudo mkdir -p /opt/local/python/etc/jupyterhub/systemd # Systemd用ディレクトリ作成
cd /opt/local/python/etc/jupyterhub/systemd # 移動
sudo touch jupyterhub.service # Systemdユニットファイル作成
エディタで jupyterhub.service を以下のように編集します。手動で起動したときにコンソールに出ていたログはすべて /var/log/jupyterhub.log に保存するようにしています。(各自調整してください)
[Unit]
Description=JupyterHub
After=syslog.target network.target
[Service]
User=root
WorkingDirectory=/opt/local/python/etc/jupyterhub
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
ExecStart=/opt/local/python/bin/jupyterhub
StandardOutput=file:/var/log/jupyterhub.log
StandardError=file:/var/log/jupyterhub.log
[Install]
WantedBy=multi-user.target
ファイルの作成が完了したら、Systemdの標準ディレクトリから見えるようにリンクを作成します。
cd /etc/systemd/system
sudo ln -s /opt/local/python/etc/jupyterhub/systemd/jupyterhub.service
6.2. Systemdサービス登録・開始
sudo systemctl daemon-reload
sudo systemctl enable jupyterhub.service # JupyterHubサービスの有効化
sudo systemctl start jupyterhub.service # JupyterHubサービスの開始
sudo systemctl status jupyterhub.service # JupyterHubサービスの状態確認
以上により、サービス登録・開始ができました。
OSを再起動し、JupyterHubが正しく起動していることを確認できればすべて完了です。
お疲れ様でした!