Paano patakbuhin ang Gemini CLI sa headless VPS
Patakbuhin ang Gemini CLI sa VPS kahit walang browser: gamitin ang kasalukuyang Node, no-sudo global install, API-key auth, at tmux para sa SSH drops.
Ano ang binubuo mo
Isang palaging gumaganang Gemini CLI sa server na pagmamay-ari mo, na maa-access gamit ang SSH at nagpapatakbo ng mahahabang agent task na nagpapatuloy kahit isara mo ang laptop. Tatlong command ang kailangan para sa installation. Ang mas matrabaho ay ang lahat ng ipinapalagay na may desktop: gustong magbukas ng browser ng Google CLI para mag-log in ka, pero walang browser ang server mo. Kaya karamihan ng gabay na ito ay tungkol sa headless na proseso, isang kasalukuyang Node na hindi ibinibigay ng distro, isang global npm install na hindi nangangailangan ng root, browserless authentication gamit ang API key na hindi mo inilalagay sa shell history, at tmux para hindi maputol ang tumatakbong task kapag nawala ang SSH session.
Ang Gemini CLI ay isang open-source na Node program (@google/gemini-cli) na gumagamit ng mga Gemini model ng Google at maaaring magbasa at magsulat ng mga file, magpatakbo ng shell command, at gumamit ng mga tool sa working directory. Sa isang VPS, isa itong maliit at palaging available na agent na maaari mong iwanang gumagana. Dahil dito, mas mahalaga kung saang account ito tumatakbo at kung anong credentials ang nakaimbak sa server kaysa sa alinmang setting dito.
Mga kinakailangan at mahahalagang limitasyon
- Isang bagong Ubuntu 24.04 KVM VPS na may root o sudo. Gumagana ang anumang KVM plan; magaan lang ang CLI mismo at ilang daang MB ng RAM ang ginagamit kapag idle.
- Node.js 20 o mas bago. Ito ang tanging mahigpit na minimum na bersyon, at mas luma rito ang distro package; tingnan ang susunod na seksyon.
- Outbound HTTPS (port 443) papunta sa mga API ng Google. Walang kailangang inbound port; client ito, hindi server, kaya hindi mo kailangang magbukas ng firewall hole para rito.
- Paraan ng authentication na hindi nangangailangan ng browser sa server: maaaring Gemini API key mula sa Google AI Studio, o SSH tunnel pabalik sa browser sa sarili mong machine. Ang API-key path ang angkop para sa mga script at unattended run.
- Docker o Podman, kung gusto mo lang ang
--sandboxisolation. Optional ito at tatalakayin malapit sa dulo.
Ito ang problemang madalas makaligtaan: ang user-friendly na gemini first-run login flow ay ginawa para sa desktop. Sinusubukan nitong magbukas ng browser at, sa headless box, maaaring mabigo o magbigay sa iyo ng link na hindi gumagana. Piliin ang auth path bago ka magsimula.
Node: the distro package is too old
Ubuntu 24.04 ships Node 18.19.1 in its own repositories, paired with npm 9.2.0. Gemini CLI's package.json declares engines: { node: ">=20" }, and npm does not hard-stop a mismatch by default, it installs anyway and prints a warning that names the gap:
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '@google/gemini-cli@0.50.0',
npm WARN EBADENGINE required: { node: '>=20' },
npm WARN EBADENGINE current: { node: 'v18.19.1', npm: '9.2.0' }
npm WARN EBADENGINE }Push past that warning and the CLI runs on an unsupported runtime, where it misbehaves or crashes the moment it reaches a Node 20+ API it expects to exist. Node 18 also reached end-of-life in April 2025, so it is a dead end either way. Install a current LTS before you install the CLI. The two clean routes are NodeSource (a system-wide signed apt repo) or nvm (a per-user version manager). Pick one.
NodeSource, if you want Node available to every user on the box:
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt-get install -y nodejs
node --versionnode --version must print v20.x or higher, v24.x is the current active LTS. Check the NodeSource page for the current setup script; the setup_24.x in the URL is the line to bump when a newer LTS lands.
nvm, if you would rather keep Node inside one user's home and never touch it with sudo:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc
nvm install --lts
node --versionThe v0.40.1 in that URL was current when this was written; check nvm's README for the latest release and swap the version in before you run it. nvm has a real advantage for this job: it installs Node and its global packages under ~/.nvm, so the global-install permission problem in the next section simply never happens. If you go the nvm route, you can skip the npm-prefix step.
I-install ang CLI nang walang sudo npm -g
Nakakatuksong gamitin ang command na sudo npm install -g @google/gemini-cli. Huwag. Ang global prefix na pagmamay-ari ng root ay nagdudulot ng mga permission error sa bawat susunod na install at nag-iiwan ng mga file na pagmamay-ari ng root sa npm cache mo. Maaari itong magdulot ng problema pagkalipas ng ilang buwan. Kung magpapatakbo ka ng plain (walang sudo) na npm install -g gamit ang system Node, makukuha mo naman ang ibang failure:
npm error code EACCES
npm error syscall mkdir
npm error path /usr/lib/node_modules/@google
npm error errno -13
npm error Error: EACCES: permission denied, mkdir '/usr/lib/node_modules/@google'Sinusubukan ng npm na magsulat sa /usr/lib, na hindi maaaring sulatan ng user mo. Hindi sudo ang solusyon. Ituro sa halip ang global prefix ng npm sa home directory mo para mapunta ang mga global install sa lokasyong pagmamay-ari mo:
mkdir -p ~/.npm-global
npm config set prefix ~/.npm-global
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
npm install -g @google/gemini-cli
gemini --versionSinasadya ang ~/.bashrc, hindi ~/.profile. Dalawang section mula ngayon, tatakbuhin mo ang CLI sa loob ng tmux. Nagsisimula ang tmux ng non-login shell na nagbabasa ng ~/.bashrc at nilalaktawan ang ~/.profile. Kaya kung nasa maling file ang linyang PATH, magiging invisible ang gemini mismo sa lugar kung saan mo ito kailangan. Ang pagpapakita ng gemini --version ng version number ang buong test. Kung gemini: command not found naman ang makuha mo, hindi nailapat ang PATH export mo; tingnan ang mga failure mode. Sa nvm, laktawan nang buo ang mga prefix line: nag-i-install na ito ng mga global package sa home directory mo.
Kung nagpatakbo ka ng sudo npm dati at nakikita mo na ngayon ang Your cache folder contains root-owned files, ayusin ito nang isang beses gamit ang sudo chown -R $(id -u):$(id -g) ~/.npm.
Ang problema sa headless authentication at kung paano ito malalampasan
Patakbuhin nang interactive ang gemini sa unang pagkakataon. Mag-aalok itong mag-log in gamit ang iyong Google account. Sa desktop, magbubukas ito ng browser tab. Sa headless VPS, walang browser. Kaya magpi-print ang flow ng localhost URL na kailangan mong buksan, o tuluyang mabibigo na may mensaheng gaya nito:
Failed to open browser. Please visit the following URL to authorize:
https://accounts.google.com/o/oauth2/v2/auth?...&redirect_uri=http://localhost:PORTAng problema ay ang redirect_uri=http://localhost:PORT. Kahit buksan mo ang URL sa laptop at aprubahan ito, magre-redirect ang Google sa http://localhost:PORT, na localhost sa server. Walang makakaabot sa port na iyon mula sa laptop mo. Hindi makukumpleto ang login.
May dalawang wastong paraan para malampasan ito.
Ang una ay API key, at ito ang tamang default para sa server. Gumawa ng key sa Google AI Studio (aistudio.google.com), at ipasa ito sa CLI bilang environment variable. Babasahin nito ang GEMINI_API_KEY at tuluyang lalaktawan ang browser flow. Narito ang mahalagang bahagi tungkol sa "pag-iwas na mapunta ito sa command history at sa mga file na mababasa ng lahat." Huwag i-type ang export GEMINI_API_KEY=AIza... sa prompt. Mapupunta ito sa ~/.bash_history bilang cleartext. Huwag din itong ilagay sa file na mababasa ng ibang user. Isulat ito sa file na mode-600 at isi-source ng shell sa pagsisimula:
umask 077
printf 'export GEMINI_API_KEY=%s\n' 'AIzaSyYOUR_KEY_HERE' > ~/.gemini_env
chmod 600 ~/.gemini_env
echo '[ -f ~/.gemini_env ] && . ~/.gemini_env' >> ~/.bashrc
source ~/.bashrcIbig sabihin ng chmod 600, ikaw lamang ang makakabasa sa file. Kumpirmahing nakarating ang key sa environment gamit ang printenv GEMINI_API_KEY. Kung walang output, babalik ang CLI sa browser flow at mabibigo. Binabasa rin nito ang .env file sa ~/.gemini/ kung mas gusto mo ang layout na iyon. Pareho pa rin ang patakaran, kaya chmod 600 ~/.gemini/.env.
Ang ikalawang paraan ay panatilihin ang login gamit ang personal na Google account, pati ang free tier nito, sa pamamagitan ng pag-tunnel ng OAuth callback pabalik sa laptop mo. Ang problema, nagbi-bind ang loopback server ng CLI sa random na port sa bawat run. Walang stable na port na maaaring i-forward maliban kung itakda mo muna ito gamit ang environment variable na OAUTH_CALLBACK_PORT, at eksaktong i-forward ang port na iyon:
# from your laptop, forward the callback port into the SSH session:
ssh -L 8085:localhost:8085 user@your-server
# then, on the server, pin the callback to the same port and start the CLI:
export OAUTH_CALLBACK_PORT=8085
geminiHindi makapagbukas ng browser ang CLI, kaya magpi-print ito ng auth URL. Buksan ito sa browser ng laptop mo at aprubahan. Kapag nag-redirect ang Google sa http://localhost:8085/..., dadalhin ng SSH forward ang request sa loopback server sa VPS at makukumpleto ang login. Kapag hindi mo itinakda ang port, mapupunta ito sa bagong random na port sa bawat run. Hindi ito masasalo ng anumang ssh -L na na-set up nang maaga. Gumagana ito, pero kailangan mong nasa harap ng browser. Kaya hindi ito angkop para sa mga script. Para sa anumang serbisyong iiwan mong tumatakbo, gamitin ang API key.
Para sa Vertex AI o isang Google Cloud project sa halip na AI Studio, itakda ang GOOGLE_API_KEY kasama ng GOOGLE_GENAI_USE_VERTEXAI=true, o ang GOOGLE_CLOUD_PROJECT para sa Code Assist licence. Sundin ang parehong disiplina sa environment variable at gamitin ang parehong mode-600 file.
Patakbuhin ito sa loob ng tmux para hindi ito mapatay ng naputol na SSH session
Ang gemini process na direktang inilulunsad mula sa iyong SSH shell ay child process ng shell na iyon. Kapag nawala ang koneksyon dahil sa pagsara ng laptop, naputol na Wi-Fi, o idle timeout, tinatanggal ng sshd ang pseudo-terminal, nakakatanggap ang shell ng SIGHUP, at isinasara rin nito ang CLI. Mamamatay kasama nito ang task na sampung minuto nang nag-e-edit ng mga file, at kapag kumonekta ka ulit, wala nang process na maaaring i-recover.
Inaayos ito ng tmux sa pamamagitan ng pagmamay-ari sa shell sa halip na sshd ang magmay-ari rito. Pareho ito ng pattern sa pagpapatakbo ng AI coding agent sa remote VPS sa loob ng tmux, at pareho rin ang paggana nito rito:
sudo apt install -y tmux
tmux new -A -s gemini
# inside the session:
gemini
# detach with Ctrl-b then d — the task keeps running
# reconnect later from any machine:
tmux attach -t geminiKumokonekta ang tmux new -A -s gemini sa session na may pangalang gemini kung mayroon na ito, at gumagawa ng session kung wala pa, kaya ito ang iisang command na dapat patakbuhin pagkatapos ng bawat login. Ang shell sa loob nito ay pagmamay-ari ng detached tmux server, hindi ng iyong SSH session, kaya magpapatuloy na gumana ang CLI kapag naputol ang koneksyon. Kumonekta ulit, mag-attach, at babalik ka sa parehong scrollback. Kung magpapatakbo ka ng ilang agent session sa isang box, tig-isa bawat tmux session, wala silang paraan para makapag-usap sa isa't isa rito. Naiiba ito sa Claude Code, kung saan maaaring magpasa ng text ang isang session sa isa pa sa parehong VPS, kaya panatilihing hiwalay ang bawat Gemini job o i-coordinate ang mga ito gamit ang mga file sa disk.
Para sa non-interactive at scripted na run, may headless mode ang Gemini CLI: ang gemini -p "summarise the failing tests in this repo" ay nagpi-print ng sagot at nag-e-exit, habang ang --output-format json ay nagbibigay ng machine-readable output na maaaring i-pipe sa ibang proseso. Ang headless mode na may API key ang eksaktong kailangan mo sa loob ng tmux session na nagpapatakbo ng matagal na batch job, o kapag inilulunsad mula sa cron entry. May isang mahalagang kondisyon: walang sini-source na login file ang cron job, kaya bigyan ang crontab line ng sarili nitong GEMINI_API_KEY, o ipa-source sa command ang ~/.gemini_env. Kung hindi, babalik ang CLI sa browser flow at mabibigo.
Sandboxing at permissions sa isang server na nagpapatakbo rin ng production
Ang agent na may shell access ay may kakayahang gumamit ng shell. Maaaring magpatakbo ng mga command ang Gemini CLI. Bilang default, nagtatanong ito bago ang bawat mapanganib na command, pero ginagamit ng mga tao ang --yolo (auto-approve every tool call). Dahil dito, maaari itong mag-delete ng mga file, mag-push sa git, o kumonekta sa mga internal service gamit ang buong authority ng user na nagpapatakbo rito. Kung nagpapatakbo rin ng production ang server, tunay na malaki ang saklaw ng posibleng pinsala. Hindi ito isang teoretikal na panganib.
Tatlong control, ayon sa lawak ng pakinabang:
- Patakbuhin ito bilang dedicated, unprivileged user. Huwag bilang root at huwag bilang miyembro ng
sudo. Gumawa ngagentuser na may sarili nitong home directory, at i-install doon ang Node at CLI. Kung mali ang interpretasyon sa isang instruction, mananatili ang epekto sa account na iyon. Ito ang pinakamahalagang desisyon. - Huwag ilagay sa server ang production credentials. Huwag maglagay ng prod
~/.aws/credentials, huwag mag-copy ng.envmula sa production, at huwag gumamit ng database password na may write access sa anumang mahalagang resource. Bigyan ito ng staging credential o read-only credential. - Gamitin ang built-in sandbox. Kapag naka-install ang Docker o Podman, pinapatakbo ng
gemini --sandbox(oGEMINI_SANDBOX=docker) ang tool calls ng agent sa loob ng container na hiwalay sa filesystem at network ng host. Hindi nito pinapalitan ang unprivileged user, pero isa itong matibay na ikalawang layer kapag aktuwal na ginagamit sa production ang parehong VPS.
Kung pinapatakbo mo ang Gemini CLI kasabay ng iba pang self-hosted tooling, halimbawa, isang MCP server na naglalantad ng mga tool sa agent sa parehong VPS, ituring ang bawat idinadagdag na capability bilang karagdagang surface na maaaring maabot ng agent. Limitahan ang mga token na ibinibigay rito sa eksaktong isang gawain.
Quota, gastos, at ang pinili mong auth path
Tinutukoy ng auth path kung paano ka sisingilin. Gumagamit ang personal na Google account (ang OAuth path) ng libreng Gemini Code Assist tier, na may aktuwal na mga limitasyon bawat minuto at bawat araw. Kapag lumampas ka sa mga ito, magbabalik ng rate-limit error ang mga request hanggang sa mag-reset ang window. Maaaring nasa free tier o may billing ang API key mula sa AI Studio, depende sa project. Kapag may billing ang key, tumataas ang mga limitasyon at sinisingil ka batay sa token. Ang Vertex at authentication ng Cloud project ay sinisingil sa pamamagitan ng Google Cloud.
Dalawang praktikal na paalala. Mabilis maubos ang quota ng unattended agent na paulit-ulit na tumatakbo sa loop, kaya i-monitor muna ito sa unang ilang paggamit bago mo ipagkatiwala sa isang cron job. At kung privacy o unmetered inference ang dahilan mo sa paggamit ng server-side model, sa halip na mga naka-host na model ng Google, ibang tool iyon. Ang pagho-host ng open LLM gamit ang Ollama sa isang VPS ay nagpapanatili ng weights at prompts sa sarili mong box, kapalit ng pagpapatakbo ng mas maliit na model kaysa sa Gemini.
Pagpapanatiling updated
Madalas maglabas ng bagong bersyon ang Gemini CLI. Dahil ini-install mo ito sa prefix na pagmamay-ari ng user, hindi kailanman kailangan ang sudo para sa mga update:
npm install -g @google/gemini-cli@latest
gemini --versionMay mga release channel: stable ang @latest, weekly preview ang @preview, at bleeding edge ang @nightly. I-pin sa @latest ang anumang package na kritikal sa iyo. Sa nvm, nasa aktibong Node version ang mga global package. Kaya pagkatapos ng nvm use para lumipat ng Node, maaaring kailangan mong i-install muli ang CLI. Basahin ang release notes sa halip na habulin ang bawat patch.
Mga failure mode, kasama ang eksaktong string
npm WARN EBADENGINE Unsupported engine ... required: { node: '>=20' }, pagkatapos ay nagka-crash ang CLI habang tumatakbo. Masyado nang luma ang Node; ang bersyon ng distro ay 18.19.1, na lampas na rin sa end-of-life. Mag-install ng Node 20+ mula sa NodeSource o nvm, kumpirmahin gamit ang node --version, at kung marami kang naka-install na Node, tingnan kung ang which node ay tumuturo sa bago at hindi sa /usr/bin/node.
npm error code EACCES / permission denied, mkdir '/usr/lib/node_modules/...'. Global install ito sa prefix na pagmamay-ari ng root. Huwag itong patakbuhin gamit ang sudo. Itakda ang npm config set prefix ~/.npm-global, ilagay ang ~/.npm-global/bin sa PATH, at muling mag-install bilang normal na user. Kung nag-iwan ang naunang sudo npm ng mga cache file na pagmamay-ari ng root (Your cache folder contains root-owned files), patakbuhin ang sudo chown -R $(id -u):$(id -g) ~/.npm.
Failed to open browser, isang login na hindi umuusad, o isang redirect_uri=http://localhost:PORT na hindi mo maabot. Nangangailangan ang OAuth flow ng browser na wala sa server, at ang localhost callback nito ay tumuturo sa server, hindi sa laptop mo. Gamitin ang API-key path (GEMINI_API_KEY), o i-pin ang OAUTH_CALLBACK_PORT, i-forward ito sa SSH gamit ang ssh -L, at buksan ang URL nang lokal.
Nawala ang process nang maputol ang SSH. Direktang pinatakbo mo ang gemini mula sa SSH shell, kaya naging child process ito ng shell na iyon at namatay kasama ng pty nang ma-disconnect. Wala nang maaaring i-recover. Simulan ang bawat session gamit ang tmux new -A -s gemini at patakbuhin ang CLI sa loob nito.
Patuloy na nagfa-fail ang auth kahit nakatakda ang key, bumabalik ang CLI sa auth picker, o nagbabalik ang request ng API key not valid na may HTTP 400. Wala ang key sa environment na nakikita ng CLI. Kumpirmahin gamit ang printenv GEMINI_API_KEY. Kung walang output, hindi na-source ang iyong ~/.gemini_env. Tingnan kung nasa ~/.bashrc ang line; binabasa ito ng interactive shells, kasama ang tmux, ngunit hindi ito binabasa ng cron at iba pang non-interactive shells. Ang sobrang space o quote sa loob ng key value ay nagdudulot din ng API key not valid.
429 / RESOURCE_EXHAUSTED / mensahe tungkol sa rate limit. Naabot mo ang quota para sa tier na ginagamit ng iyong auth. Hintaying mag-reset ang window, pabagalin ang agent, o gumamit ng billed API key. Kapag na-stuck ang agent sa retry loop, ihinto ito at tingnan kung ano ang ginagawa nito.
FAQ
Paano ko ia-authenticate ang Gemini CLI sa isang headless server?
Gumamit ng API key, hindi ng browser login. Gumawa ng key sa Google AI Studio, ilagay ito sa isang file na may mode-600 na bina-source ng shell mo (export GEMINI_API_KEY=...), at tuluyang lalaktawan ng CLI ang OAuth browser flow. Kung partikular mong gusto ang free tier para sa personal account, i-pin ang loopback port gamit ang OAUTH_CALLBACK_PORT=8085, i-forward ito pabalik sa laptop mo gamit ang ssh -L 8085:localhost:8085 user@server, at buksan nang lokal ang URL na naka-print. Gayunman, kailangan mong nasa harap ng browser, kaya hindi ito angkop para sa mga script.
Bakit nangangailangan ng sudo ang npm global install, at paano ko ito maiiwasan?
Dahil ang default global prefix ng npm ay /usr/lib/node_modules, at hindi ito maaaring sulatan ng user mo. Kaya nagfa-fail ang karaniwang npm install -g na may EACCES. Maling solusyon ang sudo npm -g, dahil nag-iiwan ito ng mga file na pagmamay-ari ng root at nagdudulot ng problema sa mga susunod na install. Ang tamang solusyon ay ituro ang prefix sa iyong home (npm config set prefix ~/.npm-global) at idagdag ang bin nito sa PATH. Maaari ka ring gumamit ng nvm, na awtomatikong nag-i-install ng global packages sa iyong home.
Paano ko mapapanatiling tumatakbo ang Gemini CLI kapag nag-disconnect ako?
Patakbuhin ito sa loob ng tmux. Namatay ang process na sinimulan mula sa iyong SSH shell kapag naputol ang connection dahil anak ito ng shell na iyon. Pinapatakbo ng tmux ang shell sa ilalim ng detached server na nananatiling buhay kahit mag-disconnect ka. Gamitin ang tmux new -A -s gemini, patakbuhin ang gemini sa loob nito, mag-detach gamit ang Ctrl-b d, at muling mag-attach sa ibang pagkakataon gamit ang tmux attach -t gemini.
Ligtas bang patakbuhin ang Gemini CLI sa production box?
Ligtas lamang ito kung maingat, dahil kayang gawin ng agent na may shell access ang anumang kayang gawin ng user na nagpapatakbo rito. Patakbuhin ito bilang dedicated unprivileged user na walang sudo, huwag maglagay ng production credentials sa machine, iwasan ang --yolo auto-approval, at gamitin ang --sandbox (Docker o Podman) upang ihiwalay sa host ang mga tool call. Mas mahalaga ang account na ginagamit nito kaysa sa anumang solong flag na ise-set mo.
Kailangan ko bang magbukas ng anumang firewall port para sa Gemini CLI?
Hindi. Client ito na gumagawa ng outbound HTTPS calls sa mga API ng Google, kaya kailangan nito ng outbound port 443 ngunit walang inbound port. Kung gagamit ka ng OAuth tunnel, ang naka-pin na callback port, halimbawa 8085, ay nasa localhost at naaabot sa pamamagitan ng iyong SSH forward, hindi sa pamamagitan ng bukas na inbound port. Panatilihing naka-lock down ang inbound traffic.