Ollama sa VPS: Ligtas na self-host ng LLM
Ang 7B model ay nangangailangan ng 8 GB RAM at 4 hanggang 10 tokens bawat segundo sa CPU. Gamitin ang 127.0.0.1:11434/v1 at isara ang port 11434.
Ano ang bubuuin mo
Isang open-weight language model na tumatakbo sa server na pagmamay-ari mo, sinasagot ang mga request sa pamamagitan ng HTTP API at, kung gusto mo, may chat page sa browser. Ang Ollama ang nagda-download ng model, naglo-load nito sa memory, at nagseserve ng mga request sa http://127.0.0.1:11434. Isang command lang ang installation. Nasa ibang bahagi ang mahihirap na gawain: pagpili ng model na kayang i-hold ng VPS mo sa RAM, at pag-iwas na aksidenteng ma-publish ang isang inference server na walang authentication sa buong internet.
Dalawang mahalagang babala muna. Mabagal magpatakbo ng maliliit na model ang CPU-only VPS, at walang built-in authentication ang API. Pareho itong ipapaliwanag nang detalyado sa ibaba, dahil dito madalas nagkakaroon ng problema.
Pagsusuri sa aktuwal na laki, gamit ang malinaw na mga numero
Ang memory footprint ng isang model ay humigit-kumulang katumbas ng file size nito, dagdag ang halos isang gigabyte para sa runtime overhead, at dagdag pa para sa context window. Ang mga default model ng Ollama ay 4-bit quantized (may label na Q4), kaya humigit-kumulang kalahating gigabyte ng RAM ang kailangan sa bawat isang bilyong parameter. Simple ang kalkulasyon, at ito ang nagtatakda ng lahat.
Ang isang 3B model gaya ng llama3.2:3b ay humigit-kumulang 2 GB ang download size at nangangailangan ng mga 4 GB na libreng RAM para tumakbo. Ang 7B o 8B model gaya ng mistral:7b o llama3.1:8b ay humigit-kumulang 5 GB sa disk at nangangailangan ng mga 8 GB na RAM; mas komportable ito sa 16 GB. Ang 13B o 14B model ay nangangailangan ng humigit-kumulang 16 GB. Ang anumang nasa 30B-to-70B range ay nangangailangan ng server na may malaking RAM o, sa praktikal na paggamit, GPU. Sa isang CPU VPS, maaaring hindi ito magkasya o magiging napakabagal ng mga sagot kaya hindi ito kapaki-pakinabang.
Pagdating sa bilis, ito ang bahaging madalas minamaliit ng mga tao. Ang CPU inference ay nakadepende sa memory bandwidth, hindi sa clock speed, at limitado ang bandwidth ng isang shared vCPU VPS. Asahan ang single-digit hanggang low-double-digit na tokens per second: maaaring umabot sa 4 hanggang 10 tokens per second ang 7-8B Q4 model, habang 10 hanggang 25 naman ang 3B model. Humigit-kumulang isang order of magnitude na mas mabilis ang GPU. Sadyang tinatayang halaga lamang ang mga ito. Ang tamang hakbang ay sukatin ang sarili mong server, at ipinapakita ng run step sa ibaba kung paano ito gawin. Magtiwala sa eval rate mo, hindi sa numerong nasa anumang article, kabilang na ang isang ito.
Ang praktikal na konklusyon: tunay na kapaki-pakinabang ang maliliit na quantized model sa CPU para sa drafting, summarization, at classification kung katanggap-tanggap sa iyo ang bilis. Para sa mas malaki o mas mabilis na model, maglaan ng budget para sa isang GPU instance.
Para matantiya ang isang partikular na model kumpara sa isang partikular na server, tantiyahin ang memory footprint nito rito:
I-install ang Ollama
May dalawang maayos na paraan. Pinakasimple ang official script sa isang bare VPS:
curl -fsSL https://ollama.com/install.sh | shLumilikha ito ng system user na may pangalang ollama, ini-install ang binary sa /usr/local/bin/ollama, at nagrerehistro ng systemd service na tinatawag na ollama.service. Awtomatikong nagsisimula ito sa boot at nakikinig sa 127.0.0.1:11434. Kumpirmahing tumatakbo ito:
systemctl status ollama
ollama --versionKung gumagamit ka na ng Docker, gamitin na lang ang container:
docker run -d --name ollama \
-p 127.0.0.1:11434:11434 \
-v ollama:/root/.ollama \
--restart always \
ollama/ollamaPansinin ang prefix na 127.0.0.1: sa port mapping. Itinatali nito ang port sa localhost lamang. Kapag -p 11434:11434 ang isinulat, ipo-publish nito ang port sa lahat ng interface. Ito ang pagkakamaling binabalaan sa seksyong pangseguridad. Pumili ng isang paraan ng pag-install. Huwag patakbuhin nang sabay ang script at ang container dahil mag-aagawan ang dalawang proseso sa port.
I-download at patakbuhin ang iyong unang model
ollama pull llama3.2:3b
ollama run llama3.2:3bIdini-download ng pull ang mga layer ng model sa disk (humigit-kumulang 2 GB para sa model na ito). Nilo-load naman ng run ang mga ito sa memory at inilalagay ka sa isang >>> prompt. Mag-type ng tanong. Maaaring umabot nang ilang segundo bago lumabas ang unang token habang nilo-load ang weights mula sa disk papunta sa RAM, at pagkatapos ay tuloy-tuloy nang lalabas ang sagot. Mag-type ng /bye upang umalis sa chat; patuloy na tatakbo sa background ang Ollama.
Tingnan kung ano ang naka-load at kung paano ito ginagamit:
ollama psAng column na PROCESSOR ang nagpapakita ng aktuwal na kalagayan. Ibig sabihin ng 100% CPU, walang GPU na ginagamit, at dito nagmumula ang pagbagal. Sukatin ang aktuwal na bilis gamit ang verbose flag:
ollama run --verbose llama3.2:3b "Write two sentences about Linux."Ang linyang eval rate na naka-print sa dulo ang bilang ng tokens per second sa hardware na ito. Ito ang bilis na dapat pagbatayan sa pagpaplano.
Kung saan nakalagay ang mga model, at kung gaano kalaking disk ang bibilhin
Kapag ini-install ng script at pinapatakbo bilang service, nakalagay ang mga model sa home directory ng user na ollama:
sudo du -sh /usr/share/ollama/.ollama/modelsKapag interactive na pinapatakbo bilang sarili mong user, nasa ~/.ollama/models ang mga ito. Sa container, nasa named volume na ollama ang mga ito. Mahalaga ito dahil mabilis dumami ang laki ng quantized weights: humigit-kumulang 2 GB ang 3B, 5 GB ang 7-8B, at 9 GB ang 14B. Kung mag-pull ka ng apat na model para ikumpara, nakagamit ka na ng 20 GB nang hindi namamalayan. Tiyaking sapat ang laki ng disk para sa mga model na balak mong panatilihin, at i-delete ang iba gamit ang ollama rm <model>. Kung may iba nang resource-intensive na application sa parehong VPS, gaya ng PhotoPrism o Immich na may photo library, ibawas muna ang espasyong ginagamit nito sa available na free space. Ituring ang matitira bilang aktuwal na budget para sa mga model.
Patakbuhin ito bilang service na kontrolado mo
Nairehistro na ng install script ang ollama.service, kaya awtomatiko itong nagre-restart kapag nag-boot ang system. Ang setting na karaniwang binabago ay kung gaano katagal mananatiling naka-load sa memory ang isang model. Sa ilang setup, binabago rin ang bind address. Ilagay ang dalawang setting sa systemd drop-in para hindi ma-overwrite ng Ollama upgrade:
sudo systemctl edit ollama.serviceIdagdag ito sa ilalim ng [Service] header na ipinapakita ng editor:
[Service]
Environment="OLLAMA_KEEP_ALIVE=30m"Tinutukoy ng OLLAMA_KEEP_ALIVE kung gaano katagal mananatili sa memory ang isang model pagkatapos ng huling request (default na 5 minuto). Itaas ito sa server na ginagamit mo buong araw para maiwasan ang paulit-ulit na pag-load ng weights. Itakda ito sa 0 sa server na limitado ang memory para mapalaya agad ang RAM kapag natapos ang request. Awtomatikong nire-reload ng systemctl edit ang unit files, kaya mag-restart upang mailapat ang pagbabago:
sudo systemctl restart ollamaAng pinakamahalagang security point
Bilang default, nagbi-bind ang Ollama sa 127.0.0.1:11434, kaya mga process lang sa VPS mismo ang makakaabot dito. Tama ang default na ito. Panatilihin ito.
Walang authentication ang API. Wala talaga. Walang API key, login, rate limit, o allow-list. Sinumang makakaabot sa port 11434 ay maaaring magpatakbo ng anumang model na na-pull mo, mag-pull ng mga bagong model, mag-delete ng mga ito, at panatilihing nasa full load ang CPU o GPU mo nang walang takdang oras. Ini-index ng mga scanner gaya ng Shodan ang mga bukas na Ollama instance nang libo-libo, at ang exposed na instance ay nahahanap at naaabuso sa loob ng ilang oras.
Kaya ito ang nag-iisang pagkakamaling hindi dapat gawin: huwag i-set ang OLLAMA_HOST=0.0.0.0 at huwag buksan ang 11434 sa firewall. Sa ganitong paraan, inilalantad sa buong internet ang isang inference server na walang authentication. Walang configuration na makapagsisiguro sa kaligtasan ng raw 11434-on-0.0.0.0, dahil walang authentication na maaaring i-configure sa Ollama; sadyang wala itong authentication. Tuntunin ito para sa partikular na serbisyong ito, hindi pagbabawal sa pagbubukas ng anumang port: kailangang tumanggap ng public traffic ang isang self-hosted na RustDesk relay para sa remote desktop upang gumana, at makatwiran ito dahil mayroon itong sarili nitong key-based authentication at maikli, dokumentadong listahan ng mga port—mga bagay na parehong wala sa Ollama.
May tatlong ligtas na paraan para ma-access ang model mula sa ibang lugar kaysa sa server mismo:
- Panatilihin itong local. Kung ang tanging caller ay isa pang program sa parehong VPS, isang cron script, isang bot, o isang MCP server na nagdudugtong ng mga tool mo sa model, iwan ang bind sa
127.0.0.1at ipa-call sa program na iyon anghttp://127.0.0.1:11434. Walang nae-expose at wala nang ibang kailangan. - I-access ito gamit ang private tunnel. Isama ang VPS sa isang WireGuard VPN na ikaw mismo ang nagho-host, itakda ang
OLLAMA_HOSTsa tunnel address (halimbawa10.8.0.1, hindi0.0.0.0), at ang mga VPN peer lang ang makakakonekta. Wala pa ring makikita ang public internet sa port 11434. - Maglagay ng reverse proxy na may authentication sa harap nito. I-terminate ang TLS at mag-require ng password o token sa nginx, Traefik, o Caddy, saka i-proxy papunta sa
127.0.0.1:11434. Pananatiliin ng Ollama ang localhost bind nito; ang proxy lang ang makikinig sa public port. Pareho ito ng setup ng paglalagay ng Let's Encrypt certificate sa nginx sa harap ng anumang local service.
Ang reverse-proxy option mismo ang ibibigay sa iyo ng chat UI sa susunod, na may aktuwal na login.
Magdagdag ng chat UI gamit ang Open WebUI, sa likod ng TLS
Ang Open WebUI ay isang self-hosted na chat interface. Patakbuhin ito sa Docker at ituro sa lokal na 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:mainAng --network=host flag ang mahalagang detalye sa Linux VPS. Inilalagay nito ang container sa network namespace ng host. Dahil dito, ang 127.0.0.1 sa loob ng container ay ang sariling loopback ng host, kaya naaabot ng container ang Ollama sa 127.0.0.1:11434 nang hindi kailangang makinig ang Ollama sa iba pang interface. Hindi gumagana rito ang bridge-network recipe na makikita mo sa ibang bahagi, --add-host=host.docker.internal:host-gateway kasama ang OLLAMA_BASE_URL=http://host.docker.internal:11434. Niresolba ng pangalang iyon ang Docker bridge gateway. Hindi naaabot sa bridge ang service na naka-bind sa 127.0.0.1 sa host, kaya mananatiling nag-uulat ang Open WebUI na hindi ito makakonekta sa Ollama.
Ang kapalit ng host networking ay makikinig na ngayon ang Open WebUI sa port 8080 ng host sa lahat ng interface. Hindi pinapansin ang anumang -p mapping, at magpi-print ang Docker ng warning tungkol dito. Kaya isara ang 8080 sa host at sa provider firewall. Gawing tanging public entry point ang TLS reverse proxy. Sa unang pagbisita, hihilingin ng Open WebUI na gumawa ka ng admin account. Ang account na iyon ang authentication layer mo, kaya gumamit ng matibay na password.
Para buksan ang chat mula sa laptop mo gamit ang HTTPS, maglagay ng TLS reverse proxy sa harap ng 127.0.0.1:8080. Kung nagro-route ka na ng ilang Docker app sa server, ang Traefik na may automatic TLS para sa maraming app ang pinakamalinis na opsyon: isang label block ang nag-iisyu ng certificate at nagro-route ng chat.example.com papunta sa Open WebUI. Nananatiling wasto ang rule mula sa security section: ang proxy ang may kontrol sa public port at login, habang nananatili ang Ollama sa localhost at nananatiling naka-firewall ang sariling 8080 ng Open WebUI.
Gamitin ang OpenAI-compatible endpoint mula sa iyong code
Sinusuportahan ng Ollama ang isang subset ng OpenAI chat API sa /v1, kaya gagana ang karamihan sa OpenAI client library kapag binago ang dalawang bagay: ang base URL at isang pansamantalang 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)Kailangan ng client library ang api_key, pero hindi ito ginagamit ng Ollama, kaya anumang string ang maaaring ilagay. Ang model ay dapat pangalan ng model na na-pull mo na; ibinabalik ang model "x" not found, try pulling it first kapag hindi kilala ang pangalan. Pareho ang ideya kapag plain curl call ang ginamit:
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"}]}'Ganito rin ikinokonekta ang model sa mga agent at editor tooling. Kung nagde-develop ka na sa server, maaaring gamitin ng mga script at plugin ang local model kasabay ng Claude Code na tumatakbo sa VPS sa loob ng tmux, kaya nananatiling pribado at mura ang drafting work sa halip na gumamit ng paid API, habang hinahawakan ng hosted model ang mas mabigat na reasoning.
Mga failure mode at ang eksaktong string na makikita mo
Napatay ang process habang bumubuo. Nag-start ka ng malaking model at nag-print ang terminal ng Killed, o ipinakita ng server log ang llama runner process has terminated: signal: killed. Pinatigil ito ng Linux OOM killer dahil mas maraming RAM ang kailangan ng model kaysa sa mayroon ang server. Kumpirmahin ang sanhi gamit ang sudo dmesg | grep -i oom, kung saan makikita mo ang linyang gaya ng Out of memory: Killed process ... (ollama). Ang solusyon ay gumamit ng mas maliit o mas heavily quantized na model, llama3.2:3b sa halip na 13B, o magdagdag ng swap upang ang load na bahagyang lumalampas sa physical RAM ay mabuhay nang mabagal sa halip na mamatay. Ginagawang mabagal na sagot ng swap ang agarang pag-crash; hindi nito ginagawang praktikal ang 70B model sa 4 GB. Tahimik ang pagpatay maliban kung mino-monitor mo ang terminal, kaya sa server na kino-query mo mula sa ibang lokasyon, ang pag-attach ng OnFailure= unit sa ollama.service na nagpo-post sa isang ntfy server na ikaw ang nagho-host para sa push alerts ay nagsasabi sa iyo kaagad kung kailan ito namatay, sa halip na matuklasan mo lamang ito sa susunod na request.
"Error: mas maraming system memory ang kailangan ng model". Tumanggi ang Ollama na i-start ang model at ipinapakita ang Error: model requires more system memory (X GiB) than is available (Y GiB). Ito ang mas maayos na bersyon ng crash sa itaas: kinalkula ng Ollama ang kailangan at huminto sa halip na ipaubaya ito sa OOM killer. Ipinapakita rin nito ang dalawang value. Pumili ng model na mas mababa sa free RAM ang requirement (suriin gamit ang free -h), paliitin ang context length, o lumipat sa mas malaking VPS. Walang flag na makapagpapasya na kasya ang model; tunay ang kinakailangang memory.
Matagal bago lumabas ang unang token, pero maayos na pagkatapos. Walang ipinapakita ang cold model sa loob ng lima hanggang tatlumpung segundo, pagkatapos ay normal na itong nag-i-stream. Sa unang pagkakataon, nilo-load ang weights mula sa disk papunta sa RAM, at mas tumatagal ito kapag mabagal ang storage. Kapag na-load na, nananatiling naka-resident ang model sa buong tagal ng OLLAMA_KEEP_ALIVE, kaya agad na sumasagot ang pangalawang prompt. Kung lumampas ang unang pag-load sa timeout sa alinmang bahagi ng call path, error ang makukuha sa halip na mabagal na sagot. Ipinapakita ng pagtukoy kung aling layer ang nag-ulat ng context deadline exceeded kung client, proxy, o mismong pag-load ang naubusan ng oras. Itaas ang value na iyon kung nakakainis ang mga pagitan, at gamitin ang ollama ps upang makita kung may model na kasalukuyang naka-load.
Mabagal ang lahat. Sampung token bawat segundo o mas mababa, nang walang anumang error. CPU inference ito na gumagana ayon sa inaasahan sa CPU inference. Ipinapakita ng ollama ps ang 100% CPU, na nangangahulugang walang GPU. Hindi ito bug at walang setting na makapag-aayos nito, dahil memory bandwidth ang limitasyon, hindi maling configuration. Gumamit ng mas maliit na model, tanggapin ang bilis, o lumipat sa GPU instance, at sukatin ang aktuwal na rate gamit ang --verbose bago magpasiyang may sira.
Connection refused mula sa ibang machine. Mula sa laptop mo, nakukuha mo ang curl: (7) Failed to connect to <ip> port 11434: Connection refused. Gumagana ito ayon sa disenyo: localhost lamang ang bina-bind ng Ollama. Huwag itong “ayusin” sa pamamagitan ng pag-bind sa 0.0.0.0, dahil iyon mismo ang maling paglalantad na nabanggit sa itaas. I-access ang model sa pamamagitan ng VPN o ng proxy na may authentication.
Inilantad mo sa internet ang 11434. Kung itinakda mo ang OLLAMA_HOST=0.0.0.0, binuksan ang firewall, at ngayon ay nakakakita ng mga model pull na hindi mo sinimulan o CPU na naka-pin sa 100% dahil sa mga hindi kilalang client, natagpuan at nagamit ka na ng iba. Ito ang pangunahing maling configuration, hindi isang bihirang sitwasyon. I-bind muli sa 127.0.0.1 o sa VPN address, isara ang 11434 sa firewall, at maglagay ng authentication sa unahan nito. Ipagpalagay na na-query ng mga hindi kilalang tao ang anumang na-access sa address na iyon habang bukas ito.
Mga backup at upgrade
Kaunti lamang ang state na maaaring mawala. Maaaring i-download muli ang mga model, kaya ang tanging dapat i-back up ay ang data volume ng Open WebUI, mga account, chat history, settings, at anumang systemd drop-in na ginawa mo. I-back up ang volume gamit ang temporary container:
docker run --rm -v open-webui:/data -v "$PWD":/backup alpine \
tar czf /backup/open-webui.tgz -C /data .I-upgrade ang Ollama sa pamamagitan ng muling pagpapatakbo ng install script. I-upgrade ang Open WebUI gamit ang docker pull ghcr.io/open-webui/open-webui:main, pagkatapos ay gawin muli ang container. Huwag mag-pin nang pangmatagalan: mabilis magbago ang kalidad ng mga model at ang runtime. Basahin ang release notes at muling magsagawa ng benchmark sa sarili mong server sa halip na umasa sa mga numero noong nakaraang quarter.
FAQ
Maaari ba talaga akong magpatakbo ng LLM sa CPU-only VPS?
Oo, pero may mga limitasyon. Ang maliliit na quantized model sa range na 3B hanggang 8B ay tumatakbo sa CPU at kapaki-pakinabang para sa pagbuo ng draft, pagbubuod, at classification. Mabagal lamang ang mga ito, karaniwang nasa single-digit hanggang low-double-digit tokens per second sa shared vCPU. Napakabagal ng anumang 13B pataas, o maaaring hindi talaga magkasya sa RAM. Para sa aktuwal na bilis o mas malalaking model, kailangan mo ng GPU instance.
Gaano karaming RAM ang kailangan ng bawat model?
Bilang tinatayang panuntunan para sa default na 4-bit quantized model: humigit-kumulang 0.5 GB ng RAM bawat isang bilyong parameter para sa weights, at dagdag na humigit-kumulang 1 GB para sa overhead at kaunti pa para sa context. Kaya kailangan ng 3B model ng humigit-kumulang 4 GB na libreng RAM, ng 7-8B model ng humigit-kumulang 8 GB, at ng 14B model ng humigit-kumulang 16 GB. Suriin ang headroom gamit ang free -h at maglaan ng espasyo para sa operating system at iba pang tumatakbo sa server.
May authentication ba ang Ollama API?
Wala. Walang built-in authentication, API key, o rate limit ang Ollama. Sinumang makakaabot sa port 11434 ay may buong kontrol dito. Ito ang dahilan kung bakit naka-bind ito sa 127.0.0.1 bilang default at kung bakit hindi mo dapat ilantad sa internet ang 11434 sa 0.0.0.0. I-access ito locally, sa private VPN, o sa pamamagitan ng reverse proxy na nagdaragdag ng login.
Paano ako magdaragdag ng web chat interface?
Patakbuhin ang Open WebUI sa Docker gamit ang --network=host upang maibahagi nito ang loopback ng host at maabot ang native Ollama sa http://127.0.0.1:11434. Pagkatapos, maglagay ng TLS reverse proxy sa harap ng port nitong 8080 para ma-access ito mula sa iyong laptop. Panatilihing sarado ang 8080 sa firewall upang ang proxy lamang ang public entry point. Ang sariling admin account ng Open WebUI ang nagbibigay ng login, at ise-set mo ang password nito sa unang launch.
Paano ko ito tatawagin mula sa sarili kong application?
Gamitin ang OpenAI-compatible endpoint sa http://127.0.0.1:11434/v1. Ituro ang anumang OpenAI SDK sa base URL na iyon, magpasa ng anumang string bilang API key dahil hindi ito ginagamit, at itakda ang model sa pangalan ng model na na-pull mo. Karaniwang tatakbo ang kasalukuyang OpenAI code nang walang pagbabago, maliban sa base URL at key.