نصب Gemini CLI روی سرور headless VPS
آموزش نصب Gemini CLI در محیط بدون مرورگر با استفاده از Node، نصب بدون sudo و استفاده از tmux برای جلوگیری از قطع شدن وظایف هنگام قطع اتصال SSH.
آنچه در حال ساخت آن هستید
یک Gemini CLI همیشه روشن روی سرور شخصی خود که از طریق SSH در دسترس است. این ابزار وظایف طولانیمدت عامل (agent) را انجام میدهد و حتی پس از بستن لپتاپ، به کار خود ادامه میدهد. فرآیند نصب تنها شامل 3 دستور است. بخش دشوار کار، تمام مواردی است که فرض را بر محیط دسکتاپ میگذارد: CLI گوگل برای ورود به حساب، نیاز به باز کردن مرورگر دارد، اما سرور شما مرورگر ندارد. بنابراین، بیشتر این راهنما بر مسیر headless تمرکز دارد؛ یعنی استفاده از نسخهای از Node که توزیع لینوکس شما ارائه نمیدهد، نصب global npm بدون نیاز به root، احراز هویت بدون مرورگر با استفاده از یک API key که از تاریخچه shell مخفی میماند، و استفاده از tmux تا قطع شدن نشست SSH باعث توقف وظایف در حال اجرا نشود.
Gemini CLI یک برنامه Node متنباز (Apache-2.0) (@google/gemini-cli) است که با مدلهای Gemini گوگل ارتباط برقرار میکند. این برنامه میتواند فایلها را بخواند و بنویسد، دستورات shell را اجرا کند و ابزارهای موجود در دایرکتوری کاری را مدیریت کند. در یک VPS، این ابزار یک عامل کوچک و همیشه در دسترس است که میتوانید برای انجام کارها رها کنید؛ به همین دلیل است که کاربری که برنامه با آن اجرا میشود و اعتبارنامههای ذخیره شده در سیستم، از هر تنظیمات دیگری در اینجا مهمتر هستند.
پیشنیازها و نکات چالشبرانگیز
- یک VPS تازه با سیستمعامل Ubuntu 24.04 و معماری KVM که دسترسی root یا sudo داشته باشد. تمام طرحهای KVM مناسب هستند؛ خودِ CLI سبک است و در حالت Idle تنها چند صد MB از RAM را اشغال میکند.
- Node.js نسخه 20 یا بالاتر. این تنها محدودیت نسخه سختافزاری است؛ پکیجهای توزیعهای لینوکس معمولاً نسخهای قدیمیتر از این دارند — بخش بعدی را مطالعه کنید.
- دسترسی HTTPS خروجی (port 443) به Google's APIs. هیچ پورت ورودی (inbound) نیاز نیست؛ این ابزار یک client است، نه server، بنابراین نیازی به باز کردن هیچ پورت در firewall ندارید.
- روشی برای احراز هویت که نیازی به مرورگر در سرور نداشته باشد: یا یک Gemini API key از Google AI Studio، یا یک SSH tunnel به مرورگر در سیستم شخصی خودتان. استفاده از API-key برای اسکریپتها و اجرای خودکار (unattended) مناسبتر است.
- Docker یا Podman، فقط در صورتی که از isolation با
--sandboxاستفاده میکنید. این بخش اختیاری است و در انتهای راهنما بررسی میشود.
نکتهای که همه را به اشتباه میاندازد: جریان ورود (login flow) در اولین اجرا با gemini برای سیستمهای دسکتاپ طراحی شده است. این فرآیند سعی میکند یک مرورگر را باز کند و در سرورهای بدون رابط گرافیکی (headless)، یا با خطا مواجه میشود و یا لینکی به شما میدهد که کار نمیکند. قبل از شروع، مسیر احراز هویت خود را مشخص کنید.
Node: نسخه توزیع بسیار قدیمی است
Ubuntu 24.04 نسخه Node 18.19.1 را در مخازن خود به همراه npm 9.2.0 ارائه میدهد. بخش package.json در Gemini CLI، نسخه engines: { node: ">=20" } را اعلام میکند و npm به صورت پیشفرض در صورت عدم تطابق متوقف نمیشود؛ بلکه نصب را انجام داده و هشداری مبنی بر وجود اختلاف نسخه نمایش میدهد:
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 }اگر از این هشدار عبور کنید، CLI روی یک runtime پشتیبانینشده اجرا میشود. در این حالت، به محض رسیدن به یک API از Node 20+ که CLI انتظار حضور آن را دارد، برنامه دچار اختلال شده یا کرش میکند. همچنین Node 18 در April 2025 به پایان عمر پشتیبانی (end-of-life) رسید، بنابراین در هر صورت این نسخه منسوخ شده است. قبل از نصب CLI، یک نسخه LTS جدید نصب کنید. دو راه اصلی وجود دارد: NodeSource (یک مخزن apt امضا شده برای کل سیستم) یا nvm (یک مدیریتکننده نسخه برای هر کاربر). یکی را انتخاب کنید.
اگر میخواهید Node برای تمام کاربران سیستم در دسترس باشد، از 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 --versionبخش node --version باید نسخه v20.x یا بالاتر را چاپ کند — نسخه v24.x نسخه فعال LTS فعلی است. برای دریافت اسکریپت نصب جدید، صفحه NodeSource را چک کنید؛ عدد setup_24.x در URL همان بخشی است که با انتشار یک LTS جدید باید آن را تغییر دهید.
اگر ترجیح میدهید Node را فقط در home یک کاربر نگه دارید و هرگز از sudo استفاده نکنید، از nvm استفاده کنید:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc
nvm install --lts
node --versionنسخه v0.40.1 در آن URL هنگام نگارش این متن بهروز بوده است؛ برای آخرین نسخه، فایل README مربوط به nvm را چک کنید و قبل از اجرا، نسخه را جایگزین کنید. nvm مزیت اصلی در این مورد دارد: این ابزار Node و پکیجهای global آن را در مسیر ~/.nvm نصب میکند، بنابراین مشکل دسترسی (permission) در نصب global که در بخش بعدی توضیح داده شده، هرگز رخ نمیدهد. اگر از مسیر nvm استفاده میکنید، میتوانید مرحله npm-prefix را نادیده بگیرید.
Install the CLI without sudo npm -g
دستور sudo npm install -g @google/gemini-cli وسوسهانگیز است، اما از آن استفاده نکنید. استفاده از یک prefix global با مالکیت root باعث بروز خطاهای permission در تمام نصبهای بعدی میشود و فایلهایی با مالکیت root در npm cache شما باقی میگذارد که ماهها بعد مشکل ایجاد میکنند. اگر یک دستور plain (بدون sudo) مانند npm install -g را روی Node سیستم اجرا کنید، با خطای زیر مواجه میشوید:
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 بنویسد، اما کاربر شما اجازه دسترسی ندارد. راه حل استفاده از sudo نیست؛ بلکه باید npm global prefix را به home directory خود تغییر دهید تا نصبهای global در مسیری که مالک آن هستید انجام شوند:
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 — که دو بخش دیگر در آن CLI را اجرا خواهید کرد — یک non-login shell اجرا میکند که ~/.bashrc را میخواند و از ~/.profile صرفنظر میکند؛ بنابراین وجود یک خط PATH در فایلی اشتباه، باعث میشود gemini دقیقاً در همان جایی که نیاز دارید، نامرئی بماند. چاپ شدن شماره نسخه توسط gemini --version، تست اصلی است. اگر به جای آن با gemini: command not found مواجه شدید، یعنی export مربوط به PATH اعمال نشده است — حالتهای خطا را بررسی کنید. اگر از nvm استفاده میکنید، خطوط مربوط به prefix را کاملاً نادیده بگیرید: این ابزار از قبل globals را در home شما نصب میکند.
اگر قبلاً sudo npm را اجرا کردهاید و اکنون Your cache folder contains root-owned files را مشاهده میکنید، آن را یک بار با sudo chown -R $(id -u):$(id -g) ~/.npm تعمیر کنید.
مشکل احراز هویت در حالت headless و روش رفع آن
در اولین اجرا، دستور gemini را به صورت interactive اجرا کنید؛ در این حالت از شما میخواهد با حساب Google خود وارد شوید. در سیستمهای دسکتاپ، یک تب در مرورگر باز میشود. در یک VPS بدون رابط گرافیکی (headless)، مرورگری وجود ندارد؛ بنابراین فرآیند یا یک URL از نوع localhost چاپ میکند که انتظار دارد آن را باز کنید، یا با خطایی شبیه به این مواجه میشود:
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 را در لپتاپ خود باز کرده و تایید کنید، Google کاربر را به http://localhost:PORT هدایت میکند؛ یعنی localhost روی سرور، پورت و آدرسی که لپتاپ شما به آن دسترسی ندارد. در این حالت فرآیند ورود هرگز تکمیل نمیشود.
دو راه حل استاندارد وجود دارد.
روش اول استفاده از API key است که انتخاب مناسبی برای سرور محسوب میشود. یک کلید در Google AI Studio (aistudio.google.com) بسازید و آن را به عنوان یک متغیر محیطی (environment variable) به CLI بدهید؛ در این صورت CLI مقدار GEMINI_API_KEY را میخواند و فرآیند مرورگر را کاملاً نادیده میگیرد. حالا به بخش «جلوگیری از ذخیره در تاریخچه و فایلهای قابل خواندن برای دیگران» میپردازیم. هرگز export GEMINI_API_KEY=AIza... را مستقیماً در خط فرمان تایپ نکنید؛ زیرا در فایل ~/.bash_history به صورت متن ساده (cleartext) ذخیره میشود. همچنین آن را در فایلی که دیگران بتوانند بخوانند قرار ندهید. آن را در فایلی با دسترسی mode-600 بنویسید که shell در هنگام شروع آن را 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 به این معناست که فقط کاربر شما میتواند فایل را بخواند. با دستور printenv GEMINI_API_KEY تایید کنید که کلید به محیط (environment) منتقل شده است؛ اگر خروجی خالی بود، CLI به فرآیند مرورگر بازمیگردد و شکست میخورد. همچنین اگر ساختار دیگری را ترجیح میدهید، CLI فایل .env را در ~/.gemini/ میخواند؛ قوانین مشابه است، بنابراین از chmod 600 ~/.gemini/.env استفاده کنید.
روش دوم، حفظ ورود با حساب شخصی Google (و سطح رایگان آن) از طریق تونل کردن (tunnelling) پاسخ بازگشتی OAuth به لپتاپ شماست. نکته اینجاست که سرور loopback در CLI در هر اجرا یک پورت تصادفی را اشغال میکند؛ بنابراین تا زمانی که پورت را با متغیر محیطی OAUTH_CALLBACK_PORT ثابت نکنید، چیزی برای فوروارد کردن وجود ندارد. پس ابتدا پورت را ثابت کنید و سپس دقیقاً همان پورت را فوروارد کنید:
# 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
geminiاز آنجایی که CLI نمیتواند مرورگر باز کند، URL احراز هویت را چاپ میکند؛ آن را در مرورگر لپتاپ خود باز کنید، تایید کنید و وقتی Google کاربر را به http://localhost:8085/... هدایت کرد، تونل SSH آن را به سرور loopback در VPS میرساند و ورود تکمیل میشود. اگر پورت را ثابت نکنید، در هر اجرا روی یک پورت تصادفی جدید قرار میگیرد که هیچ تنظیمات ssh -L از پیش تعیین شدهای نمیتواند آن را شناسایی کند. این روش کار میکند، اما نیاز به حضور شما پشت مرورگر دارد، بنابراین برای اسکریپتها مناسب نیست. برای هر چیزی که میخواهید در پسزمینه اجرا شود، از API key استفاده کنید.
برای استفاده از Vertex AI یا یک پروژه Google Cloud به جای AI Studio، متغیر GOOGLE_API_KEY را همراه با GOOGLE_GENAI_USE_VERTEXAI=true، یا از GOOGLE_CLOUD_PROJECT برای لایسنس Code Assist استفاده کنید؛ همان قوانین متغیرهای محیطی و همان فایل با mode-600 اعمال میشود.
برای جلوگیری از قطع شدن فرآیند در صورت قطع شدن نشست SSH، آن را داخل tmux اجرا کنید
هر فرآیند gemini که مستقیماً از طریق shell در SSH اجرا میکنید، فرزند آن shell است. اگر اتصال قطع شود — به دلیل بسته شدن لپتاپ، قطع شدن Wi-Fi یا timeout ناشی از عدم فعالیت — sshd ترمینال مجازی (pseudo-terminal) را از بین میبرد، shell سیگنال SIGHUP دریافت میکند و در نتیجه اتصال CLI قطع میشود. اگر در میانهی ویرایش فایلها، فرآیند 10 دقیقه سپری کرده باشد، همراه با shell از بین میرود و پس از اتصال مجدد، هیچ فرآیندی برای بازیابی وجود نخواهد داشت.
tmux این مشکل را با مالکیت shell بر آن حل میکند، به جای اینکه sshd مالک آن باشد. این دقیقاً مشابه الگوی اجرای یک عامل کدنویسی هوش مصنوعی در یک VPS از راه دور داخل tmux است و در اینجا نیز به همان صورت عمل میکند:
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دستور tmux new -A -s gemini در صورت وجود، به sessoni با نام gemini متصل میشود و اگر وجود نداشته باشد، آن را ایجاد میکند؛ بنابراین این دستور، تنها دستوری است که باید بلافاصله پس از هر بار login اجرا شود. shell داخلی متعلق به tmux server جدا شده (detached) است، نه به نشست SSH شما؛ بنابراین با قطع شدن اتصال، CLI همچنان در حال اجرا باقی میماند. با اتصال مجدد و دستور attach، به همان حالت scrollback قبلی باز میگردید.
برای اجراهای اسکریپتی و غیرتعاملی، Gemini CLI دارای حالت headless است: دستور gemini -p "summarise the failing tests in this repo" پاسخ را چاپ کرده و خارج میشود، و --output-format json خروجی با قابلیت خواندن توسط ماشین (machine-readable) را برای pipe کردن به جاهای دیگر ارائه میدهد. حالت headless همراه با یک API key دقیقاً همان چیزی است که در یک نشست tmux در حال اجرای یک batch job طولانی، یا از طریق یک cron entry نیاز دارید — با یک نکته: یک cron job هیچکدام از فایلهای login شما را source نمیکند، بنابراین حتماً خط crontab را با یک GEMINI_API_KEY اختصاصی خودتان (یا با دستور source کردن ~/.gemini_env) تنظیم کنید، در غیر این صورت CLI به حالت مرورگر بازگشت (fallback) کرده و با خطا مواجه میشود.
Sandboxing and permissions on a box that also runs production
یک Agent با دسترسی Shell، یک Shell است. Gemini CLI میتواند دستورات را اجرا کند و به صورت پیشفرض قبل از هر دستور پرخطر سوال میپرسد؛ اما کاربران از --yolo (تایید خودکار تمام فراخوانیهای ابزار) استفاده میکنند. در این حالت، Agent میتواند فایلها را حذف کند، در git push انجام دهد، یا با تمام اختیارات کاربری که تحت آن اجرا میشود، به سرویسهای داخلی درخواست ارسال کند. در سیستمی که سرویسهای Production نیز روی آن اجرا میشوند، این یک محدوده تخریب (blast radius) واقعی است، نه فرضی.
سه کنترل، به ترتیب میزان امنیت ایجاد شده:
- اجرا به عنوان یک کاربر اختصاصی و بدون امتیاز (unprivileged). نه با کاربر root و نه عضو گروه
sudo. یک کاربرagentبا home directory اختصاصی ایجاد کنید، Node و CLI را در آنجا نصب کنید؛ در این صورت، یک دستور اشتباه فقط در همان حساب کاربری محدود میماند. این مهمترین تصمیم از نظر ارزش امنیتی است. - اطلاعات حساس Production را در آن سیستم نگه ندارید. هیچ
~/.aws/credentialsمربوط به محیط production، هیچ.envکپی شده از محیط production، و هیچ رمز عبور دیتابیسی که دسترسی نوشتن به موارد حیاتی دارد، در آن قرار ندهد. به آن فقط دسترسیهای محیط staging یا read-only بدهید. - از Sandbox داخلی استفاده کنید. با نصب Docker یا Podman، ابزار
gemini --sandbox(یاGEMINI_SANDBOX=docker) فراخوانیهای ابزار Agent را درون یک کانتینر، ایزوله از فایلسیستم و شبکه میزبان، اجرا میکند. این روش جایگزین استفاده از کاربر بدون امتیاز نیست، اما وقتی همان VPS در حال انجام کارهای واقعی است، لایه امنیتی دوم قدرتمندی محسوب میشود.
اگر Gemini CLI را در کنار سایر ابزارهای self-hosted اجرا میکنید — مثلاً یک MCP server که ابزارها را در همان VPS در اختیار Agent قرار میدهد — هر قابلیت اضافه شده را به عنوان سطح حمله (surface) بیشتر برای Agent در نظر بگیرید و توکنهای داده شده به آن را دقیقاً به یک وظیفه محدود کنید.
سهمیه (Quota)، هزینه و انتخاب مسیر احراز هویت
مسیر احراز هویت تعیین میکند که هزینهها چگونه محاسبه شوند. یک حساب شخصی Google (مسیر OAuth) از سطح رایگان Gemini Code Assist استفاده میکند که دارای محدودیتهای واقعی بر حسب دقیقه و روز است؛ در صورت عبور از این محدودیتها، درخواستها با خطای rate-limit مواجه میشوند تا زمانی که بازه زمانی مجدد تنظیم شود. یک API key از AI Studio بسته به پروژه میتواند رایگان یا هزینهمحور باشد؛ یک کلید هزینهمحور، محدودیتها را افزایش داده و بر اساس تعداد token هزینه دریافت میکند. احراز هویت در Vertex و Cloud-project از طریق Google Cloud صورت میگیرد.
دو نکته کاربردی. یک agent که بدون نظارت در یک حلقه (loop) اجرا شود، میتواند سهمیه را به سرعت مصرف کند؛ بنابراین در اولین اجراها قبل از اینکه آن را به یک cron job بسپارید، تحت نظر داشته باشید. و اگر دلیل شما برای استفاده از یک مدل در سمت سرور، حفظ حریم خصوصی یا استنتاج بدون محدودیت (unmetered inference) به جای مدلهای میزبانی شده توسط Google است، این مورد ابزار متفاوتی است — میزبانی خودکار یک open LLM با Ollama روی یک VPS باعث میشود وزنها و پرامپتها روی سرور خودتان باقی بمانند، اما به قیمت اجرای مدلی بسیار کوچکتر از Gemini.
Keeping it updated
نسخههای Gemini CLI به طور مداوم منتشر میشوند. از آنجایی که شما آن را در یک prefix تحت مالکیت کاربر نصب کردهاید، برای بهروزرسانیها هرگز نیازی به sudo ندارید:
npm install -g @google/gemini-cli@latest
gemini --versionکانالهای انتشار وجود دارند: @latest نسخه پایدار (stable)، @preview نسخه پیشنمایش هفتگی (weekly preview) و @nightly نسخه bleeding edge است — برای هر موردی که به آن وابسته هستید، از نسخه @latest استفاده کنید. در nvm، بستههای global زیر مجموعه نسخه فعال Node قرار دارند، بنابراین پس از استفاده از nvm use برای تغییر نسخه Node، ممکن است نیاز به نصب مجدد CLI داشته باشید. به جای دنبال کردن هر patch، یادداشتهای انتشار (release notes) را مطالعه کنید.
حالتهای خطا و رشتههای دقیق
npm WARN EBADENGINE Unsupported engine ... required: { node: '>=20' }، و سپس کرش کردن CLI در زمان اجرا. نسخه Node قدیمی است — نسخه توزیع 18.19.1 است که از پایان عمر پشتیبانی (end-of-life) عبور کرده است. Node نسخه 20 یا بالاتر را از NodeSource یا nvm نصب کنید، با استفاده از node --version آن را تایید کنید، و اگر چندین نسخه Node نصب دارید، بررسی کنید که which node به نسخه جدید اشاره کند و نه /usr/bin/node.
npm error code EACCES / permission denied, mkdir '/usr/lib/node_modules/...'. نصب سراسری (global) در یک prefix که مالک آن root است. از sudo استفاده نکنید — npm config set prefix ~/.npm-global را تنظیم کنید، ~/.npm-global/bin را در PATH قرار دهید، و با کاربر عادی خود مجدداً نصب کنید. اگر یک sudo npm قبلی فایلهای cache با مالکیت root (Your cache folder contains root-owned files) باقی گذاشته است، دستور sudo chown -R $(id -u):$(id -g) ~/.npm را اجرا کنید.
Failed to open browser، ورودی که متوقف (hang) میشود، یا redirect_uri=http://localhost:PORT که قابل دسترسی نیست. جریان OAuth به مرورگری نیاز دارد که روی سرور وجود ندارد، و callback مربوط به localhost به سرور اشاره میکند، نه به لپتاپ شما. از مسیر API-key (GEMINI_API_KEY) استفاده کنید، یا OAUTH_CALLBACK_PORT را ثابت (pin) کنید، آن را با استفاده از ssh -L از طریق SSH فوروارد کنید، و URL را به صورت محلی باز کنید.
فرآیند با قطع شدن SSH از بین رفت. شما gemini را مستقیماً از داخل shell مربوط به SSH اجرا کردید، بنابراین این فرآیند فرزند آن shell بود و با قطع اتصال pty از بین رفت. چیزی برای بازیابی وجود ندارد. هر جلسه را با tmux new -A -s gemini شروع کنید و CLI را داخل آن اجرا کنید.
با وجود تنظیم کلید، احراز هویت همچنان شکست میخورد — CLI به منوی انتخاب احراز هویت باز میگردد، یا یک درخواست با خطای HTTP 400 و کد API key not valid پاسخ میدهد. کلید در محیطی (environment) که CLI مشاهده میکند وجود ندارد. با استفاده از printenv GEMINI_API_KEY آن را تایید کنید؛ اگر خالی است، ~/.gemini_env شما لود (sourced) نشده است — بررسی کنید که این خط در ~/.bashrc باشد؛ shellهای تعاملی (از جمله tmux) آن را میخوانند اما cron و سایر shellهای غیرتعاملی آن را نمیخوانند. وجود یک فاصله یا کوتیشن اضافی در مقدار کلید نیز باعث بروز API key not valid میشود.
429 / RESOURCE_EXHAUSTED / پیام محدودیت نرخ (rate-limit). شما به سقف مجاز (quota) برای سطح کاربری خود رسیدهاید. منتظر بازنشانی بازه زمانی باشید، سرعت عامل (agent) را کاهش دهید، یا به یک API-key پولی مهاجرت کنید. عاملی که در حلقه تلاش مجدد (retry loop) گیر کرده است، مدام با این خطا مواجه میشود — آن را متوقف کنید و بررسی کنید که چه کاری انجام میدهد.
FAQ
چگونه Gemini CLI را در یک سرور headless احراز هویت کنم؟
به جای ورود با مرورگر، از یک API key استفاده کنید. یک key در Google AI Studio ایجاد کنید، آن را در یک فایل mode-600 که shell شما آن را source میکند (export GEMINI_API_KEY=...) قرار دهید؛ در این صورت CLI فرآیند OAuth browser را کاملاً نادیده میگیرد. اگر دقیقاً نسخه رایگان حساب شخصی را میخواهید، پورت loopback را با OAUTH_CALLBACK_PORT=8085 ثابت کنید، آن را با ssh -L 8085:localhost:8085 user@server به لپتاپ خود فوروارد کنید و URL چاپ شده را به صورت محلی باز کنید؛ اما این روش نیاز به حضور شما در مرورگر دارد، بنابراین برای اسکریپتها مناسب نیست.
چرا نصب global با npm نیاز به sudo دارد و چگونه از آن اجتناب کنم؟
به این دلیل که prefix پیشفرض npm برابر با /usr/lib/node_modules است که کاربر شما اجازه نوشتن در آن را ندارد؛ بنابراین یک دستور سادهی npm install -g با خطای EACCES مواجه میشود. راه حل اشتباه استفاده از sudo npm -g است که باعث باقی ماندن فایلهایی با مالکیت root میشود و در نصبهای بعدی اختلال ایجاد میکند. راه حل درست این است که prefix را روی home خود (npm config set prefix ~/.npm-global) تنظیم کنید و bin آن را به PATH اضافه کنید، یا از nvm استفاده کنید که بستههای global را به صورت خودکار در home شما نصب میکند.
چگونه Gemini CLI را پس از قطع اتصال، در حال اجرا نگه دارم؟
آن را داخل tmux اجرا کنید. فرآیندی که از طریق shell شما در SSH شروع شده است، با قطع اتصال بسته میشود؛ زیرا آن فرآیند فرزند همان shell است. tmux shell را زیر یک سرور detached اجرا میکند که پس از قطع اتصال باقی میماند. از tmux new -A -s gemini استفاده کنید، gemini را داخل آن اجرا کنید، با Ctrl-b d detach کنید و بعداً با tmux attach -t gemini دوباره attach شوید.
آیا اجرای Gemini CLI در یک سرور production ایمن است؟
فقط با احتیاط؛ زیرا یک agent با دسترسی به shell میتواند هر کاری را که کاربرِ اجراکننده انجام میدهد، انجام دهد. آن را با یک کاربر اختصاصی و بدون سطح دسترسی sudo اجرا کنید، اطلاعات حساس production را در آن ماشین نگه ندارید، از تایید خودکار --yolo اجتناب کنید و از --sandbox (Docker یا Podman) برای جداسازی فراخوانیهای ابزار از host استفاده کنید. کاربری که برنامه تحت آن اجرا میشود، مهمتر از هر flag دیگری است که تنظیم میکنید.
آیا نیاز است پورت خاصی را در فایروال برای Gemini CLI باز کنم؟
خیر. این یک client است که درخواستهای HTTPS outbound به APIهای Google ارسال میکند؛ بنابراین به پورت outbound 443 نیاز دارد اما به هیچ پورت inbound نیازی ندارد. اگر از تونل OAuth استفاده میکنید، پورت callback ثابت شده (مثلاً 8085) روی localhost قرار دارد و از طریق SSH forward شما در دسترس است، نه از طریق یک پورت inbound باز. دسترسیهای inbound را بسته نگه دارید.