Headless VPS पर Gemini CLI कैसे चलाएं
VPS पर Gemini CLI सेटअप करें। इसमें browserless API-key auth, बिना sudo global npm install और tmux का उपयोग करके SSH session को सुरक्षित रखना शामिल है।
आप क्या बना रहे हैं
आप अपने स्वयं के server पर एक always-on Gemini CLI बना रहे हैं। इसे SSH के माध्यम से एक्सेस किया जा सकता है। यह लंबे agent tasks को चलाता है जो laptop बंद करने के बाद भी काम करते रहते हैं। installation में केवल तीन commands लगते हैं। मुख्य चुनौती desktop-based requirements को संभालना है: Google's CLI login के लिए browser खोलने की कोशिश करता है, लेकिन आपके server पर browser नहीं है। इसलिए, यह guide मुख्य रूप से headless path पर केंद्रित है — इसमें distro द्वारा न दिया जाने वाला current Node, बिना root के global npm install, shell history से सुरक्षित API key के साथ browserless auth, और tmux का उपयोग शामिल है ताकि SSH session टूटने पर भी task चलता रहे।
Gemini CLI एक open-source (Apache-2.0) Node program (@google/gemini-cli) है जो Google's Gemini models के साथ communicate करता है। यह files को read और write कर सकता है, shell commands चला सकता है, और working directory में tools को drive कर सकता है। VPS पर, यह एक छोटा और always-available agent है जिसे आप काम पर छोड़ सकते हैं — इसीलिए, यह जिस account से चलता है और server पर मौजूद credentials, यहाँ दी गई किसी भी single setting से अधिक महत्वपूर्ण हैं।
Prerequisites और महत्वपूर्ण सावधानियाँ
- root या sudo एक्सेस के साथ एक नया Ubuntu 24.04 KVM VPS. कोई भी KVM plan काम करेगा; CLI बहुत हल्का है और idle होने पर केवल कुछ hundred MB RAM लेता है।
- Node.js 20 या उससे नया version. यह एक अनिवार्य version requirement है, क्योंकि distro package इससे पुराना है — अगला section देखें।
- Google APIs के लिए Outbound HTTPS (port 443). किसी भी inbound port की आवश्यकता नहीं है; यह एक client है, server नहीं, इसलिए आपको इसके लिए firewall में कोई hole खोलने की आवश्यकता नहीं है।
- Authentication का ऐसा तरीका जिसे server पर browser की आवश्यकता न हो: या तो Google AI Studio से Gemini API key, या आपके अपने machine पर browser के माध्यम से एक SSH tunnel. API-key वाला तरीका scripts और unattended runs के लिए बेहतर है।
- Docker या Podman, केवल यदि आप
--sandboxisolation चाहते हैं। यह optional है और अंत में कवर किया गया है।
एक ऐसी समस्या जो सबको परेशान करती है: gemini का first-run login flow desktop के लिए बनाया गया है। यह browser खोलने का प्रयास करता है और headless box पर, यह या तो fail हो जाता है या आपको एक ऐसा link देता है जो काम नहीं करता। शुरू करने से पहले ही authentication path चुन लें।
Node: distro package बहुत पुराना है
Ubuntu 24.04 अपने repositories में Node 18.19.1 प्रदान करता है, जिसके साथ npm 9.2.0 आता है। Gemini CLI का package.json, engines: { node: ">=20" } को declare करता है, और npm डिफ़ॉल्ट रूप से mismatch होने पर प्रक्रिया नहीं रोकता — यह इसे install कर देता है और एक warning देता है जो इस अंतर को बताती है:
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 }इस warning को अनदेखा करने पर CLI एक unsupported runtime पर चलता है। जैसे ही यह Node 20+ API तक पहुँचता है, यह गलत व्यवहार करने लगता है या crash हो जाता है। Node 18 का end-of-life भी April 2025 में समाप्त हो चुका है, इसलिए यह दोनों ही स्थितियों में काम का नहीं है। CLI install करने पहले एक current LTS install करें। इसके दो सही तरीके NodeSource (एक system-wide signed apt repo) या nvm (एक per-user version manager) हैं। किसी एक को चुनें।
यदि आप चाहते हैं कि Node system के हर user के लिए उपलब्ध हो, तो NodeSource का उपयोग करें:
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 को v20.x या उससे उच्च version प्रिंट करना चाहिए — v24.x वर्तमान active LTS है। current setup script के लिए NodeSource page देखें; URL में setup_24.x वह line है जिसे नया LTS आने पर बदलना होगा।
यदि आप Node को केवल एक user के home directory में रखना चाहते हैं और sudo का उपयोग नहीं करना चाहते, तो nvm का उपयोग करें:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc
nvm install --lts
node --versionइस लेख के लिखते समय उस URL में v0.40.1 version current था; नवीनतम release के लिए nvm का README देखें और run करने से पहले version बदल लें। इस कार्य के लिए nvm का एक बड़ा लाभ है: यह Node और इसके global packages को ~/.nvm के अंतर्गत install करता है, इसलिए अगले section में बताई गई global-install permission की समस्या कभी नहीं आती। यदि आप nvm का उपयोग करते हैं, तो आप npm-prefix step को skip कर सकते हैं।
sudo npm -g के बिना CLI इंस्टॉल करें
sudo npm install -g @google/gemini-cli एक आकर्षक command है। इसे न चलाएं। root-owned global prefix के कारण बाद में होने वाले हर install में permission errors आएंगे। इसके अलावा, यह आपके npm cache में root-owned files छोड़ देगा, जिससे महीनों बाद समस्या होगी। system Node के विरुद्ध एक साधारण (no-sudo) npm install -g चलाएं और आपको दूसरी error मिलेगी:
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'इसका कारण यह है कि npm /usr/lib में write करने की कोशिश कर रहा है, जिसके लिए आपके पास permission नहीं है। इसका समाधान sudo नहीं है — बल्कि npm के global prefix को अपने home directory पर सेट करना है। इससे global installs उसी स्थान पर होंगे जिसका ownership आपके पास है:
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 --version~/.bashrc, न कि ~/.profile, जानबूझकर किया गया है: tmux — जिसे आप दो sections बाद CLI चलाने के लिए उपयोग करेंगे — एक non-login shell शुरू करता है जो ~/.bashrc को पढ़ता है और ~/.profile को skip कर देता है। इसलिए, गलत file में PATH line होने पर gemini ठीक उसी जगह invisible हो जाएगा जहाँ आपको इसकी आवश्यकता है। gemini --version द्वारा version number प्रिंट करना ही मुख्य test है। यदि आपको gemini: command not found मिलता है, तो इसका मतलब है कि आपका PATH export काम नहीं कर रहा है — failure modes देखें। यदि आप nvm का उपयोग कर रहे हैं, तो prefix lines को पूरी तरह skip कर दें: यह पहले से ही globals को आपके home के अंतर्गत install करता है।
यदि आपने पहले sudo npm चलाया था और अब Your cache folder contains root-owned files देख रहे हैं, तो इसे sudo chown -R $(id -u):$(id -g) ~/.npm के साथ एक बार repair करें।
Headless auth की समस्या, और इसे कैसे हल करें
पहली बार gemini को interactively चलाएँ। यह आपके Google account से login करने का विकल्प देगा। Desktop पर यह एक browser tab खोलता है। Headless VPS पर कोई browser नहीं होता, इसलिए यह या तो एक localhost URL प्रिंट करता है जिसे आपको खोलना होता है, या फिर इस तरह की error के साथ विफल हो जाता है:
Failed to open browser. Please visit the following URL to authorize:
https://accounts.google.com/o/oauth2/v2/auth?...&redirect_uri=http://localhost:PORTमुख्य समस्या redirect_uri=http://localhost:PORT है। यदि आप उस URL को अपने laptop पर खोलकर approve भी कर देते हैं, तो Google http://localhost:PORT पर redirect करता है — जो server पर localhost है। आपके laptop से इस port तक पहुँचना संभव नहीं है। Login कभी पूरा नहीं होता।
इसे हल करने के दो सही तरीके हैं।
पहला तरीका API key का उपयोग करना है, जो server के लिए सही default विकल्प है। Google AI Studio (aistudio.google.com) में एक key बनाएँ और उसे CLI को environment variable के रूप में दें; यह GEMINI_API_KEY को पढ़ता है और browser flow को पूरी तरह skip कर देता है। अब, "इसे history और world-readable files से दूर रखने" का नियम लागू होता है। prompt पर export GEMINI_API_KEY=AIza... टाइप न करें — यह cleartext में ~/.bash_history में सेव हो जाता है। इसे ऐसी file में भी न रखें जिसे अन्य लोग पढ़ सकें। इसे एक mode-600 file में लिखें जिसे shell start करते समय source कर सके:
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 ~/.bashrcchmod 600 का अर्थ है कि केवल आपका user ही उस file को पढ़ सकता है। printenv GEMINI_API_KEY के साथ पुष्टि करें कि key environment में पहुँच गई है; यदि यह कुछ भी print नहीं करता है, तो CLI browser flow का उपयोग करेगा और विफल हो जाएगा। यदि आप ~/.gemini/ में .env file का उपयोग करना चाहते हैं, तो यह भी काम करेगा — नियम समान है, इसलिए chmod 600 ~/.gemini/.env का उपयोग करें।
दूसरा तरीका OAuth callback को आपके laptop तक tunnel करके personal-Google-account login (और उसके free tier) का उपयोग करना है। समस्या यह है कि CLI का loopback server हर बार एक random port bind करता है। जब तक आप OAUTH_CALLBACK_PORT environment variable के साथ port को pin नहीं करते, तब तक इसे forward करने के लिए कोई stable port नहीं होता। इसके बाद ठीक उसी port को forward करें:
# 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
geminiCLI browser नहीं खोल सकता, इसलिए यह auth URL प्रिंट करता है; इसे अपने laptop browser में खोलें, approve करें, और जब Google http://localhost:8085/... पर redirect करता है, तो SSH forward उसे VPS पर loopback server तक पहुँचा देता है और login पूरा हो जाता है। यदि port unpinned है, तो यह हर बार एक नए random port पर जाएगा, जिसे पहले से किया गया कोई भी ssh -L नहीं पकड़ सकता। यह काम करता है, लेकिन इसके लिए आपको browser के सामने बैठना होगा, इसलिए यह scripts के लिए उपयुक्त नहीं है। किसी भी ऐसी चीज़ के लिए जिसे आप running छोड़ना चाहते हैं, API key का उपयोग करें।
AI Studio के बजाय Vertex AI या Google Cloud project के लिए, GOOGLE_API_KEY के साथ GOOGLE_GENAI_USE_VERTEXAI=true सेट करें, या Code Assist licence के लिए GOOGLE_CLOUD_PROJECT का उपयोग करें — environment-variable के नियम और mode-600 file के नियम समान रहेंगे।
इसे tmux के अंदर चलाएं ताकि SSH session टूटने पर यह बंद न हो
यदि आप gemini process को सीधे अपने SSH shell से launch करते हैं, तो वह उस shell का child process होता है। यदि connection टूट जाता है — जैसे laptop बंद होना, Wi-Fi का डिस्कनेक्ट होना, या idle timeout — तो sshd pseudo-terminal को बंद कर देता है। इसके परिणामस्वरूप shell को SIGHUP मिलता है, और CLI भी बंद हो जाता है। यदि आप files edit करते समय दस मिनट बाद connection खो देते हैं, तो वह task भी खत्म हो जाता है, और reconnect करने पर उसे recover करने के लिए कोई process नहीं मिलता।
tmux इस समस्या को हल करता है क्योंकि यह shell का owner sshd के बजाय खुद बन जाता है। यह remote VPS पर tmux के अंदर AI coding agent चलाने के समान ही pattern है, और यहाँ भी यह वैसे ही काम करता है:
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 geminiयदि gemini नाम का session मौजूद है, तो tmux new -A -s gemini उससे attach हो जाता है, अन्यथा यह नया session बना देता है। इसलिए, हर login के बाद यह एक command है जिसे चलाना चाहिए। इसके अंदर का shell detached tmux server का हिस्सा होता है, न कि आपके SSH session का, इसलिए connection टूटने पर भी CLI चलता रहता है। Reconnect करें, attach करें, और आप उसी scrollback पर वापस आ जाएंगे।
Non-interactive, scripted runs के लिए, Gemini CLI में एक headless mode है: gemini -p "summarise the failing tests in this repo" उत्तर print करके exit कर देता है, और --output-format json machine-readable output देता है जिसे कहीं और pipe किया जा सकता है। API key के साथ headless mode ही वह चीज़ है जिसकी आपको आवश्यकता तब होती है जब आप tmux session में कोई लंबा batch job चला रहे हों, या उसे cron entry से चला रहे हों — लेकिन एक सावधानी: cron job आपके किसी भी login file को source नहीं करता है, इसलिए crontab line को अपना स्वयं का GEMINI_API_KEY दें (या command को ~/.gemini_env source करने के लिए कहें), अन्यथा CLI browser flow पर switch हो जाएगा और fail हो जाएगा।
Production environment वाले box पर sandboxing और permissions
Shell access वाला agent एक shell है. Gemini CLI commands चला सकता है, और default रूप से यह हर risky command से पहले अनुमति मांगता है — लेकिन लोग --yolo (हर tool call को auto-approve करना) का उपयोग करते हैं, जिससे यह files delete कर सकता है, git पर push कर सकता है, या उस user की पूरी authority के साथ internal services को hit कर सकता है जिसके रूप में यह चल रहा है. Production environment वाले box पर, यह एक वास्तविक blast radius है, कोई hypothetical स्थिति नहीं.
तीन controls, उनके महत्व के क्रम में:
- इसे एक dedicated, unprivileged user के रूप में चलाएं. root नहीं, और न ही
sudoका member. एकagentuser बनाएं जिसका अपना home directory हो, वहां Node और CLI install करें; इससे गलत instruction केवल उसी account तक सीमित रहेगी. यह सबसे महत्वपूर्ण decision है. - Production credentials को box से दूर रखें. कोई prod
~/.aws/credentialsनहीं, production से copy किए गए.envनहीं, और ऐसी database password नहीं जिसमें किसी भी महत्वपूर्ण चीज़ के लिए write access हो. इसे staging या read-only credential दें. - Built-in sandbox का उपयोग करें. Docker या Podman installed होने पर,
gemini --sandbox(याGEMINI_SANDBOX=docker) agent के tool calls को host filesystem और network से isolated container के अंदर चलाता है. यह unprivileged user का विकल्प नहीं है, लेकिन जब वही VPS real work कर रहा हो, तो यह एक मजबूत second layer है.
यदि आप Gemini CLI को अन्य self-hosted tooling के साथ चला रहे हैं — जैसे कि उसी VPS पर agent को tools expose करने वाला MCP server — तो प्रत्येक नई capability को agent के लिए बढ़ता हुआ surface मानें, और उसे दिए गए tokens को केवल एक ही job तक सीमित रखें.
Quota, cost, and which auth path you chose
Auth path यह तय करता है कि आपका billing कैसे होगा। Personal Google account (OAuth path) Gemini Code Assist के free tier का उपयोग करता है, जिसमें per-minute और per-day की सीमाएं (limits) होती हैं; यदि आप इन्हें पार करते हैं, तो window reset होने तक requests में rate-limit error आएगा। AI Studio से प्राप्त API key, project के आधार पर free-tier या billed हो सकती है — billed key में limits अधिक होती हैं और यह per token चार्ज करती है। Vertex और Cloud-project auth का billing Google Cloud के माध्यम से होता है।
दो व्यावहारिक बातें। एक unattended agent जो loop में चल रहा हो, वह quota को तेज़ी से समाप्त कर सकता है, इसलिए इसे cron job पर चलाने से पहले कुछ बार ध्यान से monitor करें। और यदि आप Google के hosted models के बजाय privacy या unmetered inference के लिए server-side model का उपयोग करना चाहते हैं, तो वह एक अलग tool है — VPS पर Ollama के साथ open LLM को self-hosting करना weights और prompts को आपके अपने machine पर रखता है, लेकिन इसमें Gemini की तुलना में बहुत छोटा model चलाना पड़ता है।
इसे अपडेट रखना
Gemini CLI के अपडेट अक्सर आते हैं। चूंकि आपने इसे एक user-owned prefix में इंस्टॉल किया है, इसलिए अपडेट के लिए कभी भी sudo की आवश्यकता नहीं होगी:
npm install -g @google/gemini-cli@latest
gemini --versionइसके लिए अलग-अलग release channels उपलब्ध हैं: @latest stable है, @preview weekly preview है, और @nightly bleeding edge है — यदि आप किसी चीज़ पर निर्भर हैं, तो उसे @latest पर pin करें। nvm पर, global packages सक्रिय Node version के अंतर्गत रहते हैं, इसलिए Node बदलने के लिए nvm use करने के बाद आपको CLI को फिर से इंस्टॉल करना पड़ सकता है। हर patch के पीछे भागने के बजाय release notes पढ़ें।
Failure modes, with the exact strings
npm WARN EBADENGINE Unsupported engine ... required: { node: '>=20' }, और runtime पर CLI का crash होना। Node बहुत पुराना है — distro का version 18.19.1 है, जो end-of-life के बाद का है। NodeSource या nvm से Node 20+ install करें, और node --version से confirm करें। यदि आपके पास कई Nodes installed हैं, तो check करें कि which node नए version को point कर रहा है, /usr/bin/node को नहीं।
npm error code EACCES / permission denied, mkdir '/usr/lib/node_modules/...'। Root-owned prefix में global install करना। sudo का उपयोग न करें — npm config set prefix ~/.npm-global set करें, ~/.npm-global/bin को PATH पर रखें, और अपने normal user के रूप में reinstall करें। यदि किसी पुराने sudo npm ने root-owned cache files (Your cache folder contains root-owned files) छोड़ी हैं, तो sudo chown -R $(id -u):$(id -g) ~/.npm चलाएँ।
Failed to open browser, hang होने वाला login, या redirect_uri=http://localhost:PORT जिसे आप access नहीं कर सकते। OAuth flow को एक browser चाहिए जो server पर नहीं है, और इसका localhost callback server को point करता है, आपके laptop को नहीं। API-key path (GEMINI_API_KEY) का उपयोग करें, या OAUTH_CALLBACK_PORT को pin करें, ssh -L के साथ SSH पर forward करें, और URL को locally खोलें।
SSH disconnect होने पर process गायब हो गया। आपने gemini को सीधे SSH shell से चलाया था, इसलिए यह उस shell का child process था और disconnect होने पर pty के साथ बंद हो गया। इसे recover नहीं किया जा सकता। हर session को tmux new -A -s gemini के साथ शुरू करें और CLI को उसके अंदर चलाएँ।
Key set होने के बाद भी Auth fail हो रहा है — CLI वापस auth picker पर आ जाता है, या request HTTP 400 के साथ API key not valid return करती है। Key उस environment में नहीं है जिसे CLI देख रहा है। printenv GEMINI_API_KEY से confirm करें; यदि यह empty है, तो आपका ~/.gemini_env कभी source नहीं हुआ — check करें कि line ~/.bashrc में है या नहीं, जिसे interactive shells (tmux सहित) पढ़ते हैं लेकिन cron और अन्य non-interactive shells नहीं पढ़ते। Key value के अंदर एक extra space या quote भी API key not valid का कारण बनता है।
429 / RESOURCE_EXHAUSTED / rate-limit message। आपने अपने auth tier की quota limit पूरी कर ली है। Window reset होने का इंतज़ार करें, agent की speed कम करें, या billed API key पर स्विच करें। Retry loop में फँसा agent बार-बार इसे hit करता रहेगा — इसे रोकें और check करें कि यह क्या कर रहा है।
FAQ
headless server पर Gemini CLI को authenticate कैसे करें?
Browser login के बजाय API key का उपयोग करें। Google AI Studio में एक key बनाएँ, उसे एक mode-600 file में रखें जिसे आपका shell source (export GEMINI_API_KEY=...) करता हो, और CLI OAuth browser flow को पूरी तरह skip कर देगा। यदि आप विशेष रूप से personal-account free tier चाहते हैं, तो loopback port को OAUTH_CALLBACK_PORT=8085 के साथ pin करें, इसे ssh -L 8085:localhost:8085 user@server के माध्यम से अपने laptop पर forward करें, और स्थानीय रूप से printed URL खोलें — लेकिन इसके लिए browser पर आपकी उपस्थिति आवश्यक है, इसलिए यह scripts के लिए उपयुक्त नहीं है।
npm global install में sudo की आवश्यकता क्यों होती है, और मैं इससे कैसे बच सकता हूँ?
क्योंकि npm का default global prefix /usr/lib/node_modules है, जहाँ आपके user के पास write permission नहीं होती, इसलिए एक साधारण npm install -g EACCES के साथ fail हो जाता है। गलत समाधान sudo npm -g है, जो root-owned files छोड़ देता है जिससे बाद के installs में समस्या आती है। सही समाधान prefix को अपने home (npm config set prefix ~/.npm-global) पर सेट करना है और उसके bin को PATH में जोड़ना है, या nvm का उपयोग करना है, जो global packages को आपके home के अंतर्गत automatically install करता है।
disconnect होने के बाद Gemini CLI को running कैसे रखें?
इसे tmux के अंदर चलाएँ। SSH shell से शुरू किया गया process connection टूटने पर बंद हो जाता है क्योंकि वह उस shell का child process होता है; tmux shell को एक detached server के तहत चलाता है जो disconnect होने के बाद भी जीवित रहता है। tmux new -A -s gemini का उपयोग करें, इसके अंदर gemini चलाएँ, Ctrl-b d के साथ detach करें, और बाद में tmux attach -t gemini के साथ reattach करें।
क्या production box पर Gemini CLI चलाना सुरक्षित है?
केवल सावधानी के साथ, क्योंकि shell access वाला agent वह सब कुछ कर सकता है जो वह user कर सकता है जिसके रूप में वह चल रहा है। इसे बिना sudo वाले एक dedicated unprivileged user के रूप में चलाएँ, production credentials को machine से दूर रखें, --yolo auto-approval से बचें, और tool calls को host से isolate करने के लिए --sandbox (Docker या Podman) का उपयोग करें। यह जिस account के अंतर्गत चलता है, वह आपके द्वारा सेट किए गए किसी भी single flag से अधिक महत्वपूर्ण है।
क्या मुझे Gemini CLI के लिए कोई firewall ports खोलने की आवश्यकता है?
नहीं। यह एक client है जो Google के APIs को outbound HTTPS calls भेजता है, इसलिए इसे outbound port 443 की आवश्यकता होती है लेकिन किसी भी inbound port की नहीं। यदि आप OAuth tunnel का उपयोग करते हैं, तो pinned callback port (जैसे 8085) localhost पर रहता है और आपके SSH forward के माध्यम से पहुँचा जाता है, न कि किसी open inbound port के माध्यम से। Inbound traffic को locked रखें।