從零開始的 Jupyter 雲伺服器完全搭建指南

青桔_搬磚中發表於2020-12-29

0. 前言

由於移動工作的需要,相比於把程式碼環境放在本地我一直更傾向於將其放在雲端。畢竟即使用手機和 iPad 也能隨時使用和電腦相同的開發體驗這實在是太棒了不是嗎。因此這段時間為了寫作業和做一點自己的小專案,我決定用雲伺服器搭建一個隨時可用的線上 Jupyter 環境,用來寫 Python 和 Julia 。

由於網上各類教程裡五花八門的錯誤,中間也走了一些彎路,因此在這裡記錄一下,也分享給需要的其他朋友。

本篇文章主要包括的部分有:

  • 搭建環境的前期準備

  • Jupyter 環境的簡單安裝

  • 給 Jupyter 伺服器正確配置 https 和域名

  • 安裝 IJulia 環境

  • 連線 Jupyter 伺服器

其中尤其是第三步的部分,網上幾乎就沒有正確的教程。而裸露 IP 並開放防火牆的 Jupyter 不僅不安全,還容易導致各種其它問題,因此非常不推薦。

1. 搭建環境的前期準備

那麼既然要搭建一臺雲伺服器並配置域名,當然需要

  • 一臺雲伺服器(教程使用 Ubuntu 20.04 系統)

  • 一個已經實名並備案過的域名

  • 域名的 SSL 證照

  • 一個好用的 ssh 應用,個人推薦 Termius ,全平臺同步 ssh

如果不會使用 ssh 工具的話,也可以直接在雲伺服器的管理介面點選登入就可以進入 Shell 了。

2. 安裝 Conda 並更換國內源

一般來說各大服務商的雲伺服器 Ubuntu 映象都已經內建更換好了 apt 源,就如我選擇的是騰訊雲 CVM,那麼裡面的 apt 走的就是騰訊源;因此一般並不需要將 apt 源更換到國內源。如果有需要的朋友可以將其更換至清華源,上面已經有完整的教程,這裡不再贅述。不過在安裝前理應先升級一下:

$ su  # 切換到 root 使用者
$ apt update && apt upgrade

2.1 安裝 Miniconda

Conda 是一個用於科學計算的 Python 發行版,我們選擇從清華源來下載 Conda 。相比於各大傻瓜教程裡給的 Anaconda ,我更喜歡 Miniconda 。不臃腫,需要什麼包就自己裝,這對雲伺服器非常友好。

從這一步開始不推薦使用 root 使用者來進行操作。不要像有些教程裡那樣將 Jupyter 安在 root 下,還在設定裡開放許可權!如果你用的是 Ubuntu 20.04 映象的話很可能你一進來的預設使用者名稱是 ubuntu,用這個會安全很多。

首先我們訪問清華 tuna 映象站 Miniconda-release,找到最新的 miniconda 包,譬如我這裡最新的就是 Miniconda3-py39_4.9.2 。右鍵複製一下其下載連結,然後在 Bash 裡面:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-7mCuzilf-1609187496536)(https://secure-static.wolai.com/static/9Cjsrjb7QjUHWgNUKy8hnR/image.png)]

$ wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-py39_4.9.2-Linux-x86_64.sh
$ bash Miniconda3-py39_4.9.2-Linux-x86_64.sh
$ source ~/.bashrc

即可完成 Conda 的安裝。此時你應該看到你的 Bash 裡的 $ 前面多了一個 (base) 。這個就是你的 Conda 預設環境。輸入 conda —-v 來檢視你的版本,效果如下。

(base) ubuntu@VM-0-8-ubuntu:~$ conda --v
conda 4.9.2

2.2 切換 Conda 源為清華源

由於國外源的下載速度過慢,我們將 Conda 的源切換到清華 Tuna 映象站。首先我們來修改使用者目錄下的 .condarc 檔案:

$ vim ~/.condarc

如果你的系統映象喪心病狂地沒有整合 vim 那麼請自行安裝一下或者使用 vi 將就。如果連 vi 都沒有請使用 nano 。如果連 nano 都沒有還不會安裝請上門把服務商的公司砸爛。開啟後按 i 進入 Insert 模式,向內輸入:

channels:
  - defaults
show_channel_urls: true
channel_alias: https://mirrors.tuna.tsinghua.edu.cn/anaconda
default_channels:
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/pro
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2
custom_channels:
  conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud

之後按下 esc 退出 Insert,並輸入 :wq! 來退出並儲存編輯。之後執行 conda clean -i 清除索引快取,保證用的是映象站提供的索引。

3. 安裝 Jupyter Notebook 並調整設定

3.1 安裝 Jupyter

看起來很酷炫的 Jupyter Lab 經常出 Bug,因此我們還是選擇安裝較為基礎而成熟的 Jupyter Notebook 。

(base)$ conda install jupyter notebook

這樣就安好了。

3.2 配置前的準備

我們先為 Jupyter 準備一個密碼。

(base)$ python
>>> from notebook.auth import passwd
>>> passwd() # 這一步之後輸入你自己的密碼並重復輸入一次。會輸出一長串加密後的東西,將其複製下來備用。
>>> quit() # 退出 Python 環境 

將生成的這一段單引號裡的東西複製下來備用。新版本一般是用的 Argon 演算法加密。

之後將你準備好的域名的 SSL 證照下載下來(一個 pem 格式的證照檔案和一個 key 格式的檔案),並上傳到伺服器的 ~/.jupyter 資料夾裡備用。如果你的服務商只提供了 crt 形式的證照,那就:

$ openssl x509 -in xxx.crt -out xxx.pem -outform PE

3.3 設定 Jupyter 配置檔案

我們給 Jupyter 建立一個設定檔案,並開啟

(base)$ jupyter notebook --generate-config
(base)$ cd ~/.jupyter # 進入 jupyter 配置目錄
(base)$ vim jupyter_notebook_config.py # 開啟配置檔案 

之後你會看到開啟了一個全都是註釋的檔案,如下圖所示:

在這裡我們需要找到幾行,將註釋號 # 去掉並修改,當然你可以直接 cmd + F 進行搜尋。不推薦直接在檔案後面直接新增本段程式碼。

c.NotebookApp.allow_origin = '*'
c.NotebookApp.allow_remote_access = True
c.NotebookApp.certfile = '/home/ubuntu/.jupyter/xxx.pem' # 這裡是 pem 證照檔案的路徑
c.NotebookApp.ip = '127.0.0.1' # 除非 IP 裸連否則不要改成 '*'
c.NotebookApp.keyfile = '/home/ubuntu/.jupyter/xxx.key' # 這裡是 key 檔案的路徑
c.NotebookApp.notebook_dir = '/home/ubuntu/iPython' # 這裡是你想讓 Jupyter 放專案的資料夾
c.NotebookApp.password = 'xxxxxx' # 這裡放你剛剛設定密碼的時候生成的那一長串東西
c.NotebookApp.open_browser = False # 伺服器沒有瀏覽器 開什麼開
c.NotebookApp.port = 8888 # 這裡是 Jupyter 的埠,自己選個就行,反正後面要做埠轉發

改完之後同樣退出並儲存。這個時候執行

(base)$ jupyter notebook

就可以啟動 Jupyter 了,如果你選擇 IP 裸連的話,在雲伺服器安全組裡開放一下你選擇的埠,並輸入 IP:8888 就可以進入連線。

3.4 Jupyter 外掛的安裝

Jupyter 也可以安裝各種外掛。最簡單的方式就是

(base)$ conda install -c conda-forge jupyter_contrib_nbextensions

剩下的在開啟頁面之後有 GUI,這裡就不講了。

4. 給 Jupyter 配置域名訪問

這一部分是我最火大的部分。網上的各種教程幾乎全是錯的。按照他們的配置好 nginx 之後確實可以訪問 Jupyter 主頁,但建立筆記本後無法連線到 kernel,也就是根本無法使用 Python 和 Julia。我甚至懷疑他們是不是配完乾脆就再也沒用過 Jupyter。下面給出我自己的正確配置方式。

注意要首先切換到 root 使用者。

$ su # 切換到 root
$ sudo apt-get install nginx
$ source ~/.bashrc
$ cd /etc/nginx # 進入nginx 配置資料夾
$ ls # 顯示資料夾內所有檔案 

應該顯示下面的結果:

當然裡面本來是不應該有 jupyter.conf 的。那麼我們先開啟配置檔案 nginx.conf :

$ vim nginx.conf

並在裡面 http 打頭的括號裡添上一句 include /etc/nginx/jupyter.conf; ,如圖所示。

之所以這麼做是因為眾所周知把不同的東西封裝起來放在不同檔案裡是好習慣。之後我們儲存並退出編輯後,在 nginx 的配置資料夾裡新建一個 jupyter.conf 並開啟:

$ vim jupyter.conf

將下面這段內容改好之後輸進去:

server {
        # 將服務轉發到 443 埠,通過 https 訪問
        listen       443 ssl;
        
        # 這裡填寫你的域名和 IP
        server_name  xxx.com  ip.ip.ip.ip;
        
        # ssl 配置,填寫你的 pem 和 key 路徑
        ssl on;
        ssl_certificate      /home/ubuntu/.jupyter/xxx.pem;
        ssl_certificate_key  /home/ubuntu/.jupyter/xxx.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        # 下面這段是 Websocket 配置
        location / {
              # 注意這裡 8888 改成你自己用的埠,更注意這裡放 https 而不是 http
              proxy_pass https://127.0.0.1:8888;
              index  dashboard index;

              #websocket額外配置開始
              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection "upgrade";
              # 連線超時時間,不能設定太長會浪費連線資源
              proxy_connect_timeout 60s;
              # 讀超時時間
              proxy_read_timeout 500s;
              # 寫超時時間
              proxy_send_timeout 500s;
              #websocket額外配置結束

              proxy_set_header Host       $http_host;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Proto $scheme;
        }

        # 日誌路徑設定
        access_log  /home/ubuntu/.jupyter/jupyter.log;
        error_log   /home/ubuntu/.jupyter/error.log;
} 

我現在找到的所有的關於這部分配置的文章,不知道為什麼都沒有使用 Websocket 配置,導致開啟後無法連線 kernel。直到我去翻閱了整篇 Jupyter Notebook 官網的手冊,終於在一個角落發現了它用的是 Websocket 。

這個時候你已經完成了 Nginx 的配置,之後只需要啟動 Jupyter 和 Nginx 就可以訪問了:

(base) ubuntu$ nohup jupyter notebook --allow-root > jupyter.log 2>&1 & # 後臺執行 Jupyter
(base) ubuntu$ su root
(base) root$ systemctl start nginx.service # 啟動 Nginx 服務 

來,開啟你的域名,輸入密碼,開始享受 Jupyter 帶來的便利吧。

5. 安裝 Julia

除了 Python,Julia 也是科學計算的好選擇。那麼當然要裝一下。雖然 apt 裡面有 Julia 可以安裝,但並不推薦。

首先開啟我們的老朋友清華 Tuna 開源映象站 Julia-release,找到適合 x86 Linux 的最新版本,老規矩:

$ wget https://mirrors.tuna.tsinghua.edu.cn/julia-releases/bin/linux/x86/1.5/julia-1.5-latest-linux-i686.tar.gz
$ tar -xzvf julia-1.5-latest-linux-i686.tar.gz # 解壓二進位制檔案
$ cd Julia-1.5.x # 取決於你下載的版本  

之後將你的 Julia 路徑,也就是剛剛你 cd 的那個資料夾下 bin 資料夾的路徑新增到環境變數裡面:

$ cd # 進入你的使用者資料夾
$ vim ~/.bashrc # 開啟環境變數檔案 

在裡面新增兩句:

export PATH=$PATH:/home/ubuntu/julia/bin # 新增環境變數
export JULIA_PKG_SERVER=https://mirrors.tuna.tsinghua.edu.cn/julia # 新增清華源為 Julia 包源

之後同樣再

$ source ~/.bashrc # 重新整理環境變數
$ julia # 啟動 Julia 

進入 Julia 介面後,我們輸入 versioninfo() 就可以檢視當前的 Julia 版本、執行環境和所在的包源。如果你看到了 Tuna 的網址說明源設定正確了。

下一步就是安裝 IJulia,和 IPython 是一樣的東西,不過 Jupyter 就是基於 IPython的因此不必單獨安裝 IPython。

julia> using Pkg
julia> Pkg.add("IJulia") 
julia> exit() 

如果成功安裝,那麼大功告成。進入你的 Jupyter 頁面,新建選項裡除了 Python 3 就多了 Julia!

6. 在不同裝置上連線 Jupyter

在 PC 或 Mac 上顯然用瀏覽器就可以直接連線,但同樣的 UI 並不適合移動端。

這裡推薦一個 iOS 端的用於連線 Jupyter 的 App : Juno Connect。

顏值高,連線穩,如果有桌面端該有多好。

寫在後面

教程大概就到此為止了。剩下的還有一些優化(比如 Jupyter 的 css 啊之類的)還是需要自己動手做,不過就不在本教程的範圍內了。如果你發現這裡有什麼問題,歡迎與我交流。

相關文章