Linux

Linux 以 Systemd 啟動 Jupyter Notebook 搭配 Nginx 反向代理設定教學

介紹如何在 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 設定檔
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 網址對應。其餘選項可依自己的需求修改。

Systemd 啟動 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

Nginx 反向代理設定

設定好 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 了。

參考資料

Share
Published by
Office Guide

Recent Posts

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 Python ...

1 年 ago

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

1 年 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

1 年 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

1 年 ago