反向代理(URL 路徑字首)
在反向代理後將 Potato 部署到子路徑下,例如 https://host/app1/。配置部署 URL 字首,使靜態資源、標註操作和即時流在掛載路徑下都能正確解析。
Potato 可以在反向代理後以 URL 子路徑執行,例如 https://host/app1/,當多臺內部伺服器共享同一個公網 HTTPS 端點時,這種方式很常見:
https://host/app1/ -> http://127.0.0.1:8000/
https://host/app2/ -> http://127.0.0.1:8001/標註介面通過根相對 URL(/static/...、/updateinstance、/annotate、/media/...)載入靜態資源並執行操作。當 Potato 掛載到 /app1 下時,這些 URL 否則會相對公網根目錄解析,表現為 CSS 和 JS 出現 404、介面隱藏,或自動儲存失敗並提示“annotations not saved”。部署字首無需針對每個站點修改 nginx 即可解決此問題。
工作原理
下面兩種方案都會設定 WSGI 的 SCRIPT_NAME,Potato 將其作為唯一可信來源,用於服務端渲染的 url_for(...) 輸出以及暴露給瀏覽器、作為 window.config.url_prefix 的客戶端字首。該字首會包裹 fetch()、sendBeacon()、EventSource 以及根相對的 href/action/src 屬性。當未設定字首時,SCRIPT_NAME 為空,不會有任何變化,因此對於普通的 potato start 執行這是一個空操作。
方案 A — POTATO_PROXY_FIX(代理傳送轉發頭)
當你掌控代理且它能夠傳送轉發頭時使用此方案。Potato 會啟用 Werkzeug 的 ProxyFix,它會逐請求讀取 X-Forwarded-Prefix(以及 -Proto/-Host/-For)。
export POTATO_PROXY_FIX=1
potato start config.yaml -p 8000nginx,剝離字首並將其作為頭轉發:
location /app1/ {
proxy_pass http://127.0.0.1:8000/; # trailing slash strips /app1/
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Prefix /app1;
}ProxyFix 信任轉發頭。僅當應用只能通過受信任的代理訪問時才啟用 POTATO_PROXY_FIX。如果內部埠也可被直接訪問,客戶端便可能偽造 X-Forwarded-Prefix 或 -Host,從而汙染生成的 URL。
方案 B — POTATO_URL_PREFIX(代理配置無法更改)
當你無法新增轉發頭但已知公網掛載路徑時使用此方案。Potato 會自行將字首注入 SCRIPT_NAME。
export POTATO_URL_PREFIX=/app1
potato start config.yaml -p 8000代理仍必須在轉發前剝離字首,以便 Flask 收到無字首的路徑,例如 /static/styles.css:
location /app1/ {
proxy_pass http://127.0.0.1:8000/; # trailing slash strips /app1/
proxy_set_header Host $host;
}如果兩個變數都已設定,逐請求轉發的字首優先,POTATO_URL_PREFIX 作為後備。
即時流(伺服器傳送事件)
即時代理和即時編碼檢視器使用 SSE。URL 字首會自動應用,但 SSE 還需要代理在流位置上停用緩衝,否則事件會被滯留:
location /app1/api/ {
proxy_pass http://127.0.0.1:8000/api/;
proxy_set_header Host $host;
proxy_buffering off;
proxy_read_timeout 3600s;
}驗證
- 載入
https://host/app1/,確認 CSS 和 JS 載入且沒有 404。 - 進行一次標註,確認其自動儲存。
- 導航“下一個/上一個”,確認媒體和資料正常渲染。
- 如果使用即時代理評估,確認流連線並更新。
注意事項與限制
- 顯示的標註內容內部的根相對連結也會被加上字首。打算指向公網根目錄的內容作者應使用絕對 URL。
- 通過
pip安裝的部署依賴打包的靜態資源;請確保你的構建包含巢狀的static/目錄。 - Potato 2.9 把字首擴充套件到靜態檔案、客戶端 fetch 和媒體 URL,以及每個獨立頁面:管理後臺、儀表板、會話審閱和舊版 v1 頁面(#168,作者 Aldo Costa)。
- 在 Potato 2.9 之前,登入表單、
/done、/logout、/pocket、密碼重置表單和管理後臺的重定向都會忽略字首,媒體的poster、srcset和trackURL 也沒有加字首。如果經過代理的部署在其中任何一處丟失了字首,請升級。
相關內容
有關實現細節,請參閱源文件。