介紹如何在 Ubuntu Linux 中設定以 systemd 啟動 Jupyter Notebook,並透過 Nginx 的反向代理(reverse proxy)讓外部使用者使用 Jupyter Notebook。
這裡我們希望在 Ubuntu Linux 系統上以 systemd 自動啟動 Jupyter Notebook,這個內部 Jupyter Notebook 在啟動後會傾聽 127.0.0.1:8888
這個本機位址,然後我們再透過 Nginx 的反向代理讓外部使用者連線進來使用,另外為了讓 Jupyter Notebook 的網址可以跟原本 Nginx 的網頁有所區隔,我們希望 Jupyter Notebook 可以放在 https://my.domain.com/jupyter/
這樣的網址之下,不要影響原本網站的內容,以下是設定的流程與步驟。
使用以下指令,產生一份 Jupyter Notebook 設定檔範本:
# 產生 Jupyter Notebook 設定檔 jupyter-notebook --generate-config
Writing default config to: /home/myuser/.jupyter/jupyter_notebook_config.py
新產生的設定檔預設放在家目錄下的 ~/.jupyter/jupyter_notebook_config.py
,編輯此設定檔,依照自己的需求調整參數,以下是一個簡單的範例:
# 允許遠端存取 c.NotebookApp.allow_remote_access = True # URL 根目錄 c.NotebookApp.base_url = '/jupyter' # 系統根目錄 c.NotebookApp.notebook_dir = '/mnt/data/work' # 不開啟瀏覽器 c.NotebookApp.open_browser = False # 停用密碼與權杖認證 c.NotebookApp.password = '' c.NotebookApp.token = ''
這裡的 allow_remote_access
參數是設定是否允許 Jupyter Notebook 被遠端存取,由於我們會透過 Nginx 反向代理存取 Jupyter Notebook,所以這裡必須設定為 True
。URL 根目錄的設定要與 Nginx 反向代理的內部 Jupyter Notebook 網址對應。其餘選項可依自己的需求修改。
新增一個 /etc/systemd/system/jupyter-notebook.service
設定檔,內容如下:
[Unit] Description=Jupyter Notebook After=syslog.target network.target [Service] Type=simple # PID 檔案位置 PIDFile=/run/jupyter-notebook.pid # 啟動指令 ExecStart=/home/myuser/myenv/bin/jupyter-notebook --config=/home/myuser/.jupyter/jupyter_notebook_config.py # 執行 Jupyter notebook 的使用者與群組 User=myuser Group=mygroup # 工作目錄 WorkingDirectory=/mnt/data/work # 自動重新啟動 Restart=always RestartSec=10 [Install] WantedBy=multi-user.target
這裡的 ExecStart
參數要指定 Jupyter Notebook 的啟動指令,jupyter-notebook
指令的所在路徑可以使用 which
指令查詢:
# 查詢 jupyter-notebook 指令路徑
which jupyter-notebook
/home/myuser/myenv/bin/jupyter-notebook
而 jupyter-notebook
指令所附加的 --config
參數要指定為上面我們修改好的 Jupyter Notebook 設定檔。
接著重新載入 systemd 設定檔,設定開機自動啟動 Jupyter Notebook 服務,同時將 Jupyter Notebook 服務啟動:
# 重新載入設定檔 sudo systemctl daemon-reload # 設定開機自動啟動 Jupyter Notebook 服務 sudo systemctl enable jupyter-notebook.service # 啟動 Jupyter Notebook 服務 sudo systemctl start jupyter-notebook.service
設定好 systemd 啟動 Jupyter Notebook 服務之後,接著要設定 Nginx 的反向代理,讓外部使用者透過 Nginx 連線至 Jupyter Notebook。
編輯 Nginx 網站的設定檔(例如 /etc/nginx/sites-available/default
),先在 server
區塊之前加入一段 WebSocket 標頭的設定,然後在 server
區塊中加入一段 Jupyter Notebook 的反向代理設定,完整的設定範例如下:
# WebSocket 標頭的頂層 http 設定 # If Upgrade is defined, Connection = upgrade # If Upgrade is empty, Connection = close map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { # ... # Jupyter Notebook 設定 location /jupyter/ { # 內部 Jupyter Notebook 網址 proxy_pass http://127.0.0.1:8888/jupyter/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # WebSocket 標頭 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; } }
這裡 proxy_pass
所指定的內部 Jupyter Notebook 網址,必須與 Jupyter Notebook URL 根目錄(NotebookApp.base_url
)設定相同。proxy_http_version
必須指定為 1.1
,如果沒有加上這一行,Jupyter Notebook 在使用時會發生不斷重複連線 kernel 的問題。
修改完成後,測試 Nginx 的設定檔:
# 測試 Nginx 設定檔 sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
若沒有出現錯誤,即可重新啟動 Nginx 網頁服務:
# 重新啟動 Nginx 服務
sudo systemctl restart nginx
這時候用瀏覽器開啟 https://my.domain.com/jupyter/
這樣的外部網址,就可以透過 Nginx 的反向代理存取內部的 Jupyter Notebook 了。