如何在 VPS 架設 Ollama 並安全存取 LLM
本文教學如何在 VPS 上部署 Ollama 並透過 127.0.0.1:11434/v1 安全存取。針對 7B 模型在 CPU 運作時每秒僅 4 到 10 tokens 的效能,提供硬體規格評估與安全性建議,避免將 API 直接暴露於網際網路。
您的建置目標
您將在自有伺服器上運行單一開源權重語言模型。您可以透過 HTTP API 進行查詢,或在瀏覽器中使用聊天頁面。Ollama 負責下載模型、將其載入記憶體,並在 http://127.0.0.1:11434 上提供服務。安裝只需執行單一指令。主要的挑戰在於其他部分:如何選擇 VPS 記憶體足以負載的模型,以及如何避免將未經身份驗證的推論伺服器直接暴露於網際網路。
首先有兩點重要提醒。僅使用 CPU 的 VPS 執行小型模型速度較慢,且 API 完全沒有內建身份驗證機制。下文將詳細說明這兩點,因為這兩點是常見的錯誤來源。
規格評估:數據實測
模型的記憶體佔用量大約等於檔案大小,加上約 1 GB 的執行時開銷(runtime overhead),以及部分用於 context window 的額外空間。Ollama 的預設模型為 4-bit 量化(標記為 Q4),每 10 億個參數(parameters)大約消耗 0.5 GB 的 RAM。因此,計算方式非常簡單,這決定了硬體需求。
像 llama3.2:3b 這樣的 3B 模型,下載大小約為 2 GB,執行時需要約 4 GB 的可用 RAM。像 mistral:7b 或 llama3.1:8b 這樣的 7B 或 8B 模型,磁碟佔用約 5 GB,需要約 8 GB 的 RAM,若要運作順暢建議準備 16 GB。13B 或 14B 模型大約需要 16 GB。30B 到 70B 範圍的模型需要大容量 RAM 的主機,或者實際情況下需要 GPU —— 在使用 CPU 的 VPS 上,模型會因為空間不足無法執行,或是回應速度過慢而失去實用價值。
接著是速度,這是最常被低估的部分。CPU 推論(inference)受限於記憶體頻寬(memory bandwidth)而非時脈頻率(clock speed),而共享 vCPU 的 VPS 頻寬有限。預期速度僅為每秒個位數到低雙位數的 tokens:一個 7-8B Q4 模型可能達到每秒 4 到 10 個 tokens,3B 模型則為每秒 10 到 25 個 tokens。GPU 的速度大約快一個數量級。這些數據僅供參考 —— 最準確的做法是測試您自己的主機,下方的執行步驟將示範如何操作。請信任您的 eval rate,而非任何文章(包含本文)中的數據。
實際結論:如果您能接受處理速度,CPU 上的小型量化模型在草擬、摘要與分類任務上確實有用。若有更大或更快的需求,請預算 GPU 執行個體(instance)的成本。
若要針對特定主機評估特定模型,請在此估算其記憶體佔用量:
安裝 Ollama
有兩種乾淨的安裝方式。在全新的 VPS 上,使用官方指令碼最為簡單:
curl -fsSL https://ollama.com/install.sh | sh此操作會建立名為 ollama 的系統使用者,將 binary 安裝至 /usr/local/bin/ollama,並註冊一個名為 ollama.service 的 systemd 服務。該服務會在開機時啟動並綁定 127.0.0.1:11434。請確認服務已正常運作:
systemctl status ollama
ollama --version若您已在使用 Docker,請改用容器方式安裝:
docker run -d --name ollama \
-p 127.0.0.1:11434:11434 \
-v ollama:/root/.ollama \
--restart always \
ollama/ollama請注意 port mapping 中的 127.0.0.1: 前綴。這會將 port 僅綁定至 localhost。若寫成 -p 11434:11434 則會將其發佈至所有 interface,這正是安全性章節所警告的錯誤做法。請擇一安裝方式;請勿同時執行指令碼與容器,否則兩個 process 會發生 port 衝突。
Pull and run your first model
ollama pull llama3.2:3b
ollama run llama3.2:3bpull 會將模型層下載至磁碟(此模型約 2 GB)。run 會將其載入記憶體,並進入 >>> 提示字元介面。請輸入問題。由於權重正從磁碟載入至 RAM,第一個 token 可能需要數秒,隨後答案會開始串流輸出。輸入 /bye 結束對話;Ollama 會繼續在背景執行。
查看已載入內容及其佔用空間:
ollama psPROCESSOR 欄位顯示實際資訊。100% CPU 表示未使用 GPU,這就是速度緩慢的原因。請使用 verbose flag 來測量實際速度:
ollama run --verbose llama3.2:3b "Write two sentences about Linux."結尾處印出的 eval rate 行代表此硬體上的每秒 token 數。請以此數值作為規劃依據。
模型存放位置與磁碟容量規劃
若透過 script 安裝並以 service 執行,模型會存放於 ollama 使用者的家目錄:
sudo du -sh /usr/share/ollama/.ollama/models若以使用者身份進行互動式執行,模型會存放於 ~/.ollama/models。在 container 中,模型則存放於名為 ollama 的 named volume。由於量化權重(quantized weights)佔用空間極快,因此規劃容量至關重要:3B 模型約需 2 GB,7-8B 約需 5 GB,14B 約需 9 GB。若下載四個模型進行比較,在不知不覺中就會消耗 20 GB。請根據預計保留的模型數量來規劃磁碟容量,並使用 ollama rm <model> 刪除其餘模型。
以受控服務方式執行
安裝指令碼已註冊 ollama.service,因此無需額外設定即可在開機時自動重啟。建議修改的設定包含模型保留時間,以及在某些配置下的 bind address。將這些設定寫入 systemd drop-in 檔案中,可避免 Ollama 升級時覆蓋設定:
sudo systemctl edit ollama.service請將以下內容新增至編輯器顯示的 [Service] 標題下方:
[Service]
Environment="OLLAMA_KEEP_ALIVE=30m"OLLAMA_KEEP_ALIVE 定義最後一次請求後模型保留在記憶體中的時間(預設為 5 分鐘)。若伺服器全天都在處理請求,請調高此值以避免重複載入 weights;若伺服器資源有限,請將其設為 0,以便在請求結束後立即釋放 RAM。systemctl edit 會為您重新載入 unit files,請執行 restart 以套用變更:
sudo systemctl restart ollama最重要的安全性重點
預設情況下,Ollama 會綁定至 127.0.0.1:11434,因此只有該 VPS 本機上的程序可以存取。此預設設定是正確的,請予以保留。
API 完全沒有身份驗證機制。沒有 API key、沒有登入機制、沒有速率限制(rate limit),也沒有允許清單(allow-list)。任何可以存取 port 11434 的人,都可以執行您已下載的任何模型、下載新模型、刪除模型,並讓您的 CPU 或 GPU 無限期維持在滿載狀態。像 Shodan 這樣的掃描器會索引成千上萬個公開的 Ollama 實例,一旦實例暴露,會在數小時內被發現並遭到濫用。
因此,請絕對不要犯下這個錯誤:不要設定 OLLAMA_HOST=0.0.0.0 並在防火牆中開啟 11434。這會將一個未經身份驗證的推論伺服器發布到整個網際網路。無論如何配置,直接將 11434 暴露於 0.0.0.0 都是不安全的,因為 Ollama 本身沒有可配置的安全性設定——它根本沒有身份驗證功能。
若要從該主機以外的地方安全地存取模型,有三種方法:
- 保持本地端存取。如果唯一的呼叫者是同一台 VPS 上的另一個程式(例如 cron 腳本、機器人或 將您的工具與模型橋接的 MCP server),請將綁定設定維持在
127.0.0.1,並讓該程式呼叫http://127.0.0.1:11434。這樣既不會暴露任何內容,也不需要額外設定。 - 透過私有隧道存取。將 VPS 連接到 您自行架設的 WireGuard VPN,將
OLLAMA_HOST設定為隧道位址(例如10.8.0.1,而非0.0.0.0),如此一來只有 VPN 節點可以連線。公網仍無法看到 11434 port 的任何內容。 - 在前端部署具備身份驗證功能的反向代理(reverse proxy)。在 nginx、Traefik 或 Caddy 上進行 TLS 終止並要求密碼或 token,然後代理至
127.0.0.1:11434。Ollama 維持其 localhost 綁定;反向代理是唯一在公用 port 上監聽的服務。這與在任何本地服務前 為 nginx 加上 Let's Encrypt 憑證 的做法相同。
接下來提供的聊天 UI 介面,就是採用反向代理方案並附帶真實登入功能的實作方式。
使用 Open WebUI 並透過 TLS 建立聊天介面
Open WebUI 是一個自架的聊天介面。請使用 Docker 執行,並將其指向本地的 Ollama:
docker run -d \
--name open-webui \
--network=host \
-e OLLAMA_BASE_URL=http://127.0.0.1:11434 \
-v open-webui:/app/backend/data \
--restart always \
ghcr.io/open-webui/open-webui:main在 Linux VPS 上,--network=host 旗標是關鍵細節。它會將容器置於主機的網路命名空間(network namespace),因此容器內的 127.0.0.1 即為主機的 loopback。如此一來,即使 Ollama 未監聽其他介面,容器仍能透過 127.0.0.1:11434 存取 Ollama。其他地方常見的 bridge-network 設定方式(即使用 --add-host=host.docker.internal:host-gateway 搭配 OLLAMA_BASE_URL=http://host.docker.internal:11434)在此並不適用:該名稱會解析至 Docker bridge gateway,而綁定於主機 127.0.0.1 的服務無法透過 bridge 存取,這會導致 Open WebUI 無法連線至 Ollama。
使用 host networking 的權衡點在於,Open WebUI 現在會在主機的所有介面上監聽 8080 埠號;任何 -p 映射都會失效,且 Docker 會印出相關警告。因此,請在主機與供應商防火牆中關閉 8080,並僅讓 TLS 反向代理作為唯一的對外入口。首次訪問時,Open WebUI 會要求建立管理員帳戶;該帳戶即為您的驗證層,請設定強密碼。
若要透過 HTTPS 從筆記型電腦開啟聊天功能,請在 127.0.0.1:8080 前方部署 TLS 反向代理。如果您已在該主機上運行多個 Docker 應用程式,使用 Traefik 實現多應用程式自動 TLS 是最簡潔的方案:只需一個 label 區塊即可核發憑證並將 chat.example.com 路由至 Open WebUI。安全原則依然適用:代理伺服器負責對外埠號與登入驗證,而 Ollama 保持在 localhost,Open WebUI 自身的 8080 則維持防火牆保護。
從程式碼中使用相容於 OpenAI 的端點
Ollama 在 /v1 提供 OpenAI Chat API 的子集,因此只需修改兩項設定,大多數 OpenAI 客戶端函式庫即可運作:base URL 與隨意填寫的 key。
from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:11434/v1", api_key="ollama")
resp = client.chat.completions.create(
model="llama3.2:3b",
messages=[{"role": "user", "content": "Name three Linux distributions."}],
)
print(resp.choices[0].message.content)客戶端函式庫需要 api_key,但 Ollama 會忽略此值,因此填寫任何字串皆可。model 必須是您已 pull 的模型名稱;若名稱錯誤會回傳 model "x" not found, try pulling it first。使用 curl 指令的邏輯相同:
curl http://127.0.0.1:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"llama3.2:3b","messages":[{"role":"user","content":"Hello"}]}'這也是將模型整合至 agent 與 editor 工具的方法。若您已在該主機進行開發,本地模型可以支援腳本與 plugin,並與 在 tmux 內的 VPS 執行 Claude Code 並行。這能在處理繁重推理任務時使用託管模型,同時將低成本且具隱私性的草稿工作保留在本地,避免使用付費 API。
Failure modes, with the exact strings you will see
程序在生成中途被 "Killed"。 您啟動大型模型後,終端機顯示 Killed,或伺服器日誌顯示 llama runner process has terminated: signal: killed。這是因為模型所需的 RAM 超過主機容量,導致 Linux OOM killer 終止程序。請使用 sudo dmesg | grep -i oom 確認原因,您會看到類似 Out of memory: Killed process ... (ollama) 的內容。解決方法是改用較小或量化程度更高的模型(例如使用 llama3.2:3b 而非 13B),或是增加 swap 空間,讓僅微幅超過實體 RAM 的負載能緩慢運行而非直接崩潰。Swap 能將即時崩潰轉化為緩慢回應,但無法讓 70B 模型在 4 GB 環境下變得實用。
"Error: model requires more system memory"。 Ollama 無法啟動模型並顯示 Error: model requires more system memory (X GiB) than is available (Y GiB)。這是上述崩潰情況的預防版本:Ollama 進行運算後主動停止,而非等待 OOM killer 介入。它甚至會直接提供兩個數值。請選擇需求低於可用 RAM(請使用 free -h 檢查)的模型、縮減 context length,或升級至更大的 VPS。任何 flag 都無法讓模型強行載入,因為記憶體限制是真實存在的。
第一個 token 產生極慢,之後恢復正常。 冷啟動模型在 5 到 30 秒內不會有任何輸出,隨後才開始正常串流。該停頓是因為權重正從磁碟載入至 RAM,儲存裝置速度越慢,延遲越久。模型載入後會保留 OLLAMA_KEEP_ALIVE,因此第二次提示詞會立即得到回應。若無法接受此間隔,請調高該數值,並使用 ollama ps 查看模型是否已載入。
整體速度極慢。 每秒僅 10 個 token 或更少,且完全沒有錯誤。這是 CPU 推論的正常表現。ollama ps 顯示 100% CPU,代表目前未使用 GPU。這並非錯誤,也沒有設定可以修復,因為限制在於記憶體頻寬而非配置錯誤。請使用較小的模型、接受此速度,或改用 GPU 實例;在判定系統故障前,請先使用 --verbose 測量實際速率。
來自其他機器的 Connection refused。 從您的筆記型電腦會收到 curl: (7) Failed to connect to <ip> port 11434: Connection refused。這是預期行為:Ollama 僅綁定 localhost。請勿透過綁定 0.0.0.0 來「修復」此問題,因為這正是上述提到的安全性錯誤。請改用 VPN 或經過驗證的 proxy 來存取模型。
您將 11434 暴露於網際網路。 如果您設定了 OLLAMA_HOST=0.0.0.0 並開啟防火牆,接著發現出現未經授權的模型下載,或 CPU 被不明客戶端佔用至 100%,代表您已被入侵並被利用。這是最嚴重的錯誤,而非極端案例。請將綁定改回 127.0.0.1 或 VPN 位址,在防火牆關閉 11434 埠,並在前端加入身份驗證。請假設在該埠開啟期間,任何可連線至該位址的請求都來自陌生人。
Backups and upgrades
系統狀態損失極小。模型可以重新下載,因此僅需備份 Open WebUI 的 data volume(包含帳戶、對話紀錄、設定)以及您撰寫的任何 systemd drop-in。請使用臨時容器備份該 volume:
docker run --rm -v open-webui:/data -v "$PWD":/backup alpine \
tar czf /backup/open-webui.tgz -C /data .透過重新執行安裝指令碼來升級 Ollama;使用 docker pull ghcr.io/open-webui/open-webui:main 升級 Open WebUI 並重新建立容器。請勿進行長期版本鎖定:模型品質與執行環境變化迅速,請閱讀 release notes 並在您的設備上重新進行 benchmark,而非依賴上一季的數據。
FAQ
我真的能在僅有 CPU 的 VPS 上執行 LLM 嗎?
可以,但有限制。3B 到 8B 範圍內的輕量化量化模型可在 CPU 上執行,且對於草擬、摘要與分類任務非常實用。但在共享 vCPU 上,速度僅有每秒個位數至低雙位數的 tokens。13B 以上的模型速度極慢,或根本無法放入 RAM。若需要高速或執行大型模型,您需要 GPU 實例。
每個模型需要多少 RAM?
對於預設的 4-bit 量化模型,有一個粗略的規則:每 1B 參數約需 0.5 GB RAM 用於權重,外加約 1 GB 的額外開銷,以及更多用於 context 的空間。因此,3B 模型約需 4 GB 剩餘空間,7-8B 模型約需 8 GB,14B 模型約需 16 GB。請使用 free -h 檢查您的剩餘空間,並為作業系統及系統內其他程序預留空間。
Ollama API 有身份驗證機制嗎?
沒有。Ollama 沒有內建身份驗證、API key 或速率限制。任何可以連線至 port 11434 的人都能完全控制它。這正是為什麼它預設會綁定 127.0.0.1,以及為什麼您絕不能將 11434 暴露於 0.0.0.0 的網際網路中。請透過本地端、私有 VPN 或加上登入功能的反向代理進行連線。
如何新增 Web Chat 介面?
使用 Docker 執行 Open WebUI 並搭配 --network=host,使其共用主機的 loopback 並透過 http://127.0.0.1:11434 存取原生的 Ollama,接著在它的 port 8080 前方架設一個 TLS 反向代理,以便從您的筆電存取。請在防火牆關閉 8080,確保反向代理是唯一的公開入口。Open WebUI 自帶管理員帳號提供登入功能,您需在首次啟動時設定密碼。
如何從我自己的應用程式呼叫它?
使用位於 http://127.0.0.1:11434/v1 的 OpenAI 相容端點。將任何 OpenAI SDK 指向該 Base URL,並傳入任何字串作為 API key(因為它會被忽略),然後將 model 設定為您已下載的模型名稱。現有的 OpenAI 程式碼通常只需修改 Base URL 與 key 即可直接執行。