SSD Nodes Learn Hosting plans →
راهنماها Matt Connorتوسط Matt Connor · به‌روزرسانی شده 2026-08-27

اجرای Gemini CLI روی سرور مجازی بدون رابط گرافیکی

راهنمای کامل اجرای Gemini CLI روی VPS با استفاده از Node.js و tmux. یاد بگیرید چگونه بدون نیاز به مرورگر احراز هویت کنید و با نصب بدون sudo، وظایف طولانی را مدیریت کنید.

آنچه در حال ساخت آن هستید

یک CLI برای Gemini که همیشه روی سرور شخصی شما در دسترس است، از طریق SSH قابل دسترسی بوده و وظایف طولانی‌مدت عامل (agent) را اجرا می‌کند که پس از بستن لپ‌تاپ همچنان به کار خود ادامه می‌دهند. نصب این ابزار تنها با 3 دستور انجام می‌شود. آنچه نیاز به تلاش دارد، مواردی است که پیش‌فرض‌های محیط دسکتاپ را در نظر می‌گیرند: CLI گوگل برای ورود به سیستم نیاز به باز کردن مرورگر دارد، در حالی که سرور شما فاقد رابط گرافیکی است. بنابراین، بخش عمده این راهنما شامل مسیر headless، نصب نسخه به‌روز Node که در مخازن توزیع شما موجود نیست، نصب سراسری npm بدون نیاز به دسترسی root، احراز هویت بدون مرورگر با استفاده از یک API key که در تاریخچه shell ذخیره نمی‌شود، و استفاده از tmux برای جلوگیری از توقف وظایف در صورت قطع اتصال SSH است.

Gemini CLI یک برنامه Node متن‌باز (تحت مجوز Apache-2.0) است (@google/gemini-cli) که با مدل‌های Gemini گوگل ارتباط برقرار می‌کند و توانایی خواندن و نوشتن فایل‌ها، اجرای دستورات shell و مدیریت ابزارها در دایرکتوری کاری را دارد. روی یک VPS، این ابزار یک عامل کوچک و همیشه در دسترس است که می‌توانید آن را در حال اجرا رها کنید؛ به همین دلیل، حسابی که با آن اجرا می‌شود و اعتبارنامه‌هایی که روی سرور قرار دارند، از هر تنظیم دیگری در این راهنما اهمیت بیشتری دارند.

پیش‌نیازها و نکات مهم

  • یک سرور مجازی KVM با سیستم‌عامل Ubuntu 24.04 و دسترسی root یا sudo. هر پلن KVM مناسب است؛ رابط خط فرمان (CLI) بسیار سبک است و در حالت استراحت به چند صد مگابایت رم نیاز دارد.
  • نسخه Node.js 20 یا جدیدتر. این یک حداقل نسخه اجباری است و بسته موجود در مخازن توزیع (distro) قدیمی‌تر از این نسخه است؛ بخش بعدی را ببینید.
  • دسترسی خروجی HTTPS (پورت 443) به APIهای Google. نیازی به باز کردن پورت‌های ورودی نیست؛ این یک کلاینت است، نه یک سرور، بنابراین هیچ حفره‌ای در فایروال برای آن ایجاد نمی‌کنید.
  • روشی برای احراز هویت که به مرورگر روی سرور نیاز نداشته باشد: یا یک Gemini API key از Google AI Studio، یا یک تونل SSH به مرورگر روی سیستم شخصی خودتان. روش استفاده از API key برای اسکریپت‌ها و اجراهای خودکار (unattended) مناسب‌تر است.
  • Docker یا Podman، فقط در صورتی که به ایزوله‌سازی --sandbox نیاز دارید. این مورد اختیاری است و در انتهای آموزش پوشش داده شده است.

نکته‌ای که اکثر کاربران را دچار مشکل می‌کند: فرآیند ورود اولیه gemini برای محیط دسکتاپ طراحی شده است. این فرآیند تلاش می‌کند یک مرورگر را باز کند و در یک سرور بدون رابط گرافیکی (headless)، یا با خطا مواجه می‌شود یا لینکی به شما می‌دهد که کار نمی‌کند. پیش از شروع، مسیر احراز هویت خود را مشخص کنید.

نکته: بسته توزیع‌شده بسیار قدیمی است

اوبونتو 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 یا بالاتر که انتظار وجودش را دارد، دچار اختلال یا crash می‌شود. Node 18 همچنین در آوریل 2025 به پایان عمر خود (EOL) رسیده است، بنابراین در هر صورت یک بن‌بست محسوب می‌شود. پیش از نصب CLI، یک نسخه LTS فعلی نصب کنید. دو روش تمیز برای این کار وجود دارد: NodeSource (یک مخزن apt امضاشده در سطح سیستم) یا nvm (یک مدیریت نسخه برای هر کاربر). یکی را انتخاب کنید.

NodeSource، اگر می‌خواهید Node برای تمام کاربران سیستم در دسترس باشد:

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 جدیدتر باید به‌روزرسانی شود.

nvm، اگر ترجیح می‌دهید Node را در دایرکتوری home یک کاربر نگه دارید و هرگز با sudo به آن دست نزنید:

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 نصب می‌کند، بنابراین مشکل مجوز در نصب‌های سراسری که در بخش بعدی به آن اشاره می‌شود، هرگز رخ نخواهد داد. اگر روش nvm را انتخاب کردید، می‌توانید مرحله npm-prefix را نادیده بگیرید.

نصب CLI بدون sudo npm -g

دستور وسوسه‌انگیز sudo npm install -g @google/gemini-cli است. این کار را انجام ندهید. استفاده از یک پیشوند (prefix) سراسری که مالک آن root است، در هر نصب بعدی باعث خطای دسترسی می‌شود و فایل‌هایی با مالکیت root در کش npm باقی می‌گذارد که ماه‌ها بعد برای شما مشکل‌ساز خواهند شد. اجرای یک npm install -g ساده (بدون sudo) روی یک 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 را به دایرکتوری home خود هدایت کنید تا نصب‌های سراسری در جایی قرار بگیرند که مالکیت آن با شماست:

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 استفاده می‌کنید، از خطوط مربوط به پیشوند صرف‌نظر کنید؛ چرا که nvm به‌طور خودکار بسته‌های سراسری را در دایرکتوری home شما نصب می‌کند.

اگر در گذشته sudo npm را اجرا کرده‌اید و اکنون با Your cache folder contains root-owned files مواجه می‌شوید، آن را یک‌بار با دستور sudo chown -R $(id -u):$(id -g) ~/.npm تعمیر کنید.

مشکل احراز هویت در محیط‌های headless و نحوه عبور از آن

ابزار gemini را برای اولین بار به‌صورت تعاملی اجرا کنید تا پیشنهاد ورود به سیستم با حساب 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) ایجاد کنید و آن را به‌عنوان یک متغیر محیطی به CLI بدهید؛ ابزار مقدار GEMINI_API_KEY را می‌خواند و فرآیند مبتنی بر مرورگر را کاملاً نادیده می‌گیرد. اکنون به بخش «دور نگه داشتن از تاریخچه و فایل‌های قابل خواندن برای همه» می‌رسیم. دستور export GEMINI_API_KEY=AIza... را در خط فرمان تایپ نکنید، زیرا به‌صورت متن ساده در ~/.bash_history ذخیره می‌شود؛ همچنین آن را در فایلی که دیگران اجازه خواندنش را دارند قرار ندهید. آن را در فایلی با مجوز 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 ~/.bashrc

chmod 600 به این معناست که فقط کاربر شما اجازه خواندن فایل را دارد. با دستور printenv GEMINI_API_KEY تأیید کنید که کلید به محیط منتقل شده است؛ اگر خروجی خالی باشد، CLI به سراغ فرآیند مرورگر می‌رود و با شکست مواجه می‌شود. همچنین اگر این ساختار را ترجیح می‌دهید، ابزار فایل .env را در مسیر ~/.gemini/ می‌خواند؛ قانون همان است، پس chmod 600 ~/.gemini/.env را رعایت کنید.

روش دوم، حفظ ورود به سیستم با حساب شخصی Google (و استفاده از سطح رایگان آن) از طریق تونل کردن callback مربوط به OAuth به لپ‌تاپ شماست. نکته اینجاست که سرور loopback ابزار CLI در هر بار اجرا یک پورت تصادفی انتخاب می‌کند، بنابراین هیچ پورت ثابتی برای forward کردن وجود ندارد مگر اینکه ابتدا آن را با متغیر محیطی OAUTH_CALLBACK_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
gemini

از آنجا که CLI نمی‌تواند مرورگر را باز کند، URL احراز هویت را چاپ می‌کند؛ آن را در مرورگر لپ‌تاپ خود باز کرده و تأیید کنید. وقتی Google به http://localhost:8085/... تغییر مسیر می‌دهد، SSH forward آن را به سرور loopback روی VPS منتقل کرده و ورود تکمیل می‌شود. اگر پورت را ثابت نکنید، در هر بار اجرا یک پورت تصادفی جدید انتخاب می‌شود که هیچ ssh -L از پیش تنظیم‌شده‌ای نمی‌تواند آن را دریافت کند. این روش کار می‌کند، اما نیاز دارد که شما پشت مرورگر باشید، بنابراین برای اسکریپت‌ها مناسب نیست. برای هر سرویسی که قرار است به‌صورت مداوم اجرا شود، از API key استفاده کنید.

برای استفاده از Vertex AI یا یک پروژه Google Cloud به‌جای AI Studio، متغیر GOOGLE_API_KEY را همراه با GOOGLE_GENAI_USE_VERTEXAI=true، یا برای لایسنس Code Assist متغیر GOOGLE_CLOUD_PROJECT را تنظیم کنید؛ همان انضباط در استفاده از متغیرهای محیطی و همان فایل با مجوز 600 را رعایت کنید.

اجرای آن در tmux تا قطع شدن نشست SSH باعث توقف آن نشود

هر فرآیند gemini که مستقیماً از داخل shell نشست SSH خود اجرا می‌کنید، فرزند همان shell محسوب می‌شود. قطع شدن اتصال، بستن لپ‌تاپ، ناپایداری Wi-Fi، یا timeout شدن نشست، باعث می‌شود sshd ترمینال مجازی را از بین ببرد، shell سیگنال SIGHUP دریافت کند و در نتیجه فرآیند متوقف شود. کاری که ده دقیقه برای ویرایش فایل‌ها زمان برده است با این اتفاق از بین می‌رود و پس از اتصال مجدد، هیچ فرآیندی برای بازیابی وجود ندارد.

ابزار tmux با در اختیار گرفتن مالکیت shell به جای sshd، این مشکل را حل می‌کند. این همان الگویی است که در اجرای یک AI coding agent روی یک 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 به نشستی با نام gemini متصل می‌شود؛ اگر این نشست وجود داشته باشد به آن وصل می‌شود و در غیر این صورت آن را ایجاد می‌کند. بنابراین این تنها دستوری است که باید بلافاصله پس از هر بار ورود به سیستم اجرا کنید. shell داخل آن متعلق به سرور tmux است که در پس‌زمینه جدا از نشست SSH شما اجرا می‌شود، بنابراین قطع شدن اتصال باعث توقف CLI نمی‌شود. پس از اتصال مجدد، با attach کردن به نشست، دقیقاً به همان وضعیت قبلی و تاریخچه خروجی‌ها بازمی‌گردید. اگر چندین نشست agent را روی یک سرور اجرا می‌کنید، هر کدام در یک نشست tmux مجزا قرار می‌گیرند و برخلاف Claude Code که در آن یک نشست می‌تواند متن را به نشست دیگری روی همان VPS منتقل کند، در اینجا راهی برای ارتباط مستقیم بین آن‌ها وجود ندارد؛ بنابراین هر کار Gemini را مستقل نگه دارید یا آن‌ها را از طریق فایل‌های روی دیسک هماهنگ کنید.

برای اجرای اسکریپتی و غیرتعاملی، Gemini CLI دارای یک حالت headless است: gemini -p "summarise the failing tests in this repo" پاسخ را چاپ کرده و خارج می‌شود، و --output-format json خروجی قابل‌فهم برای ماشین ارائه می‌دهد تا بتوانید آن را به دستورات دیگر pipe کنید. حالت headless به همراه یک API key دقیقاً همان چیزی است که برای اجرای یک batch job طولانی داخل نشست tmux یا اجرای آن از طریق cron نیاز دارید، با یک نکته مهم: cron job هیچ‌کدام از فایل‌های login شما را source نمی‌کند، بنابراین در خط crontab باید متغیر GEMINI_API_KEY را به صورت دستی مقداردهی کنید (یا دستور را طوری تنظیم کنید که ~/.gemini_env را source کند)، در غیر این صورت CLI به سراغ جریان احراز هویت مرورگر می‌رود و با خطا مواجه می‌شود.

سندباکس‌سازی و مجوزها در سروری که سرویس‌های عملیاتی (Production) را اجرا می‌کند

عاملی که دسترسی shell دارد، در واقع یک shell است. Gemini CLI می‌تواند دستورات را اجرا کند و به‌صورت پیش‌فرض پیش از اجرای هر دستور پرخطر از شما تأیید می‌گیرد، اما کاربران اغلب از --yolo (تأیید خودکار تمام فراخوانی‌های ابزار) استفاده می‌کنند. در این حالت، عامل می‌تواند فایل‌ها را حذف کند، تغییرات را به git بفرستد یا با تمام اختیارات کاربری که با آن اجرا شده، به سرویس‌های داخلی دسترسی پیدا کند. در سروری که سرویس‌های عملیاتی را میزبانی می‌کند، این موضوع یک ریسک واقعی و بزرگ است، نه یک احتمال فرضی.

سه کنترل امنیتی، به ترتیب اولویت و اثربخشی:

  • اجرا با یک کاربر اختصاصی و بدون امتیاز (unprivileged). نه root و نه عضوی از گروه sudo. یک کاربر agent با home directory اختصاصی بسازید، Node و CLI را در آن نصب کنید تا در صورت اجرای اشتباه یک دستور، اثرات آن محدود به همان حساب کاربری باقی بماند. این مهم‌ترین تصمیم امنیتی است.
  • عدم نگهداری اعتبارنامه‌های عملیاتی (Production credentials) روی سرور. هیچ ~/.aws/credentials عملیاتی، هیچ .env کپی‌شده از محیط عملیاتی، و هیچ رمز عبور دیتابیسی با دسترسی نوشتن روی داده‌های حساس را روی این سرور قرار ندهید. فقط از اعتبارنامه‌های محیط staging یا با دسترسی read-only استفاده کنید.
  • استفاده از سندباکس داخلی. اگر Docker یا Podman نصب باشد، gemini --sandbox (یا GEMINI_SANDBOX=docker) فراخوانی‌های ابزار توسط عامل را درون یک کانتینر اجرا می‌کند که از فایل‌سیستم میزبان و شبکه ایزوله است. این جایگزین کاربر بدون امتیاز نیست، اما یک لایه دفاعی قدرتمند در زمانی است که همان VPS در حال انجام کارهای واقعی است.

اگر Gemini CLI را در کنار سایر ابزارهای self-hosted اجرا می‌کنید، مثلاً یک سرور MCP که ابزارها را روی همان VPS در اختیار عامل قرار می‌دهد، هر قابلیت جدیدی که اضافه می‌کنید را به عنوان سطح دسترسی جدیدی برای عامل در نظر بگیرید و توکن‌هایی که به آن می‌دهید را دقیقاً محدود به یک وظیفه خاص کنید.

سهمیه، هزینه و مسیر احراز هویتی که انتخاب کردید

مسیر احراز هویت تعیین‌کننده نحوه صورت‌حساب شماست. یک حساب کاربری شخصی Google (مسیر OAuth) از سطح رایگان Gemini Code Assist استفاده می‌کند که دارای محدودیت‌های واقعی در هر دقیقه و هر روز است؛ در صورت عبور از این محدودیت‌ها، درخواست‌ها تا زمان بازنشانی بازه زمانی، خطای rate-limit برمی‌گردانند. یک API key از AI Studio بسته به پروژه می‌تواند در سطح رایگان یا پولی باشد؛ کلید پولی محدودیت‌ها را افزایش داده و به ازای هر توکن هزینه دریافت می‌کند. احراز هویت Vertex و Cloud-project از طریق Google Cloud صورت‌حساب می‌شود.

دو نکته کاربردی: یک عامل (agent) بدون نظارت در یک حلقه می‌تواند سهمیه را به‌سرعت مصرف کند، بنابراین پیش از آنکه اجرای آن را به یک cron job بسپارید، چند بار اول آن را زیر نظر بگیرید. و اگر دلیل شما برای استفاده از یک مدل سمت سرور، حفظ حریم خصوصی یا استنتاج نامحدود (unmetered) به‌جای استفاده از مدل‌های میزبانی‌شده توسط Google است، این موضوع ابزار متفاوتی را می‌طلبد؛ میزبانی شخصی یک LLM متن‌باز با Ollama روی یک VPS وزن‌ها و پرامپت‌ها را روی سرور خودتان نگه می‌دارد، که البته به قیمت اجرای مدلی بسیار کوچک‌تر از Gemini تمام می‌شود.

به‌روز نگه‌داشتن

ابزار Gemini CLI به‌طور مرتب عرضه (release) می‌شود. از آنجا که آن را در یک prefix متعلق به کاربر نصب کرده‌اید، برای به‌روزرسانی هرگز نیازی به sudo نیست:

npm install -g @google/gemini-cli@latest
gemini --version

کانال‌های عرضه مختلفی وجود دارد: @latest نسخه پایدار، @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 استفاده می‌کند که به پایان عمر خود رسیده است. Node 20 یا بالاتر را از NodeSource یا nvm نصب کنید، با node --version آن را تأیید کنید، و اگر چندین نسخه Node نصب دارید، بررسی کنید که which node به نسخه جدید اشاره کند و نه /usr/bin/node.

npm error code EACCES / permission denied, mkdir '/usr/lib/node_modules/...'. نصب سراسری (global) در مسیری که متعلق به root است. از sudo استفاده نکنید، npm config set prefix ~/.npm-global را تنظیم کنید، ~/.npm-global/bin را روی PATH قرار دهید و دوباره با کاربر عادی خود نصب کنید. اگر یک sudo npm قبلی فایل‌های کش با مالکیت root (Your cache folder contains root-owned files) باقی گذاشته است، sudo chown -R $(id -u):$(id -g) ~/.npm را اجرا کنید.

Failed to open browser، لاگینی که متوقف می‌شود، یا redirect_uri=http://localhost:PORT که به آن دسترسی ندارید. فرآیند OAuth به مرورگری نیاز دارد که سرور آن را ندارد و callback مربوط به localhost به خود سرور اشاره می‌کند، نه لپ‌تاپ شما. از مسیر API-key (GEMINI_API_KEY) استفاده کنید، یا OAUTH_CALLBACK_PORT را پین کنید، آن را از طریق SSH با ssh -L فوروارد کنید و URL را به‌صورت محلی باز کنید.

فرآیند با قطع شدن SSH ناپدید شد. شما gemini را مستقیماً از شل SSH اجرا کردید، بنابراین فرزند آن شل بود و با قطع شدن pty از بین رفت. چیزی برای بازیابی وجود ندارد. هر نشست را با tmux new -A -s gemini شروع کنید و CLI را داخل آن اجرا کنید.

احراز هویت با وجود تنظیم کلید همچنان شکست می‌خورد، CLI به انتخابگر احراز هویت بازمی‌گردد، یا یک درخواست API key not valid با HTTP 400 برمی‌گرداند. کلید در محیطی که CLI می‌بیند وجود ندارد. با printenv GEMINI_API_KEY تأیید کنید؛ اگر خالی است، ~/.gemini_env شما هرگز source نشده است. بررسی کنید که این خط در ~/.bashrc وجود داشته باشد، فایلی که شل‌های تعاملی (از جمله tmux) آن را می‌خوانند اما cron و سایر شل‌های غیرتعاملی آن را نمی‌خوانند. یک فاصله یا کوتیشن اضافی داخل مقدار کلید نیز باعث ایجاد API key not valid می‌شود.

429 / RESOURCE_EXHAUSTED / پیام محدودیت نرخ (rate-limit). شما به سقف سهمیه (quota) مربوط به سطح احراز هویت خود رسیده‌اید. منتظر بمانید تا بازه زمانی ریست شود، سرعت ایجنت را کاهش دهید یا به یک API key پولی مهاجرت کنید. ایجنتی که در حلقه تلاش مجدد (retry loop) گیر کرده است همچنان این خطا را دریافت می‌کند؛ آن را متوقف کرده و بررسی کنید چه کاری انجام می‌دهد.

FAQ

چگونه Gemini CLI را روی یک سرور headless احراز هویت کنم؟

از یک API key استفاده کنید، نه ورود از طریق مرورگر. یک کلید در Google AI Studio بسازید، آن را در فایلی با دسترسی 600 قرار دهید که shell شما آن را source می‌کند (export GEMINI_API_KEY=...)؛ در این صورت CLI به‌طور کامل از جریان OAuth مرورگر عبور می‌کند. اگر مشخصاً به دنبال استفاده از طرح رایگان حساب شخصی هستید، پورت loopback را با OAUTH_CALLBACK_PORT=8085 ثابت کنید، آن را با ssh -L 8085:localhost:8085 user@server به لپ‌تاپ خود فوروارد کنید و URL نمایش‌داده‌شده را به‌صورت محلی باز کنید. اما این روش مستلزم حضور شما در کنار یک مرورگر است و برای اسکریپت‌ها مناسب نیست.

چرا نصب سراسری npm نیاز به sudo دارد و چگونه از آن اجتناب کنم؟

زیرا پیشوند سراسری پیش‌فرض npm برابر با /usr/lib/node_modules است که کاربر شما اجازه نوشتن در آن را ندارد، بنابراین یک دستور ساده npm install -g با خطای EACCES مواجه می‌شود. راه‌حل اشتباه استفاده از sudo npm -g است که فایل‌هایی با مالکیت root باقی می‌گذارد و باعث خرابی نصب‌های بعدی می‌شود. راه‌حل درست این است که پیشوند را به دایرکتوری home خود (npm config set prefix ~/.npm-global) تغییر دهید و مسیر bin آن را به PATH اضافه کنید، یا از nvm استفاده کنید که بسته‌های سراسری را به‌طور خودکار در home شما نصب می‌کند.

چگونه Gemini CLI را پس از قطع اتصال فعال نگه دارم؟

آن را داخل tmux اجرا کنید. فرآیندی که از shell مربوط به SSH شروع شده باشد، با قطع اتصال از بین می‌رود زیرا فرزند آن shell محسوب می‌شود؛ tmux shell را تحت یک سرور جداگانه اجرا می‌کند که پس از قطع اتصال باقی می‌ماند. از tmux new -A -s gemini استفاده کنید، gemini را داخل آن اجرا کنید، با Ctrl-b d جدا شوید و بعداً با tmux attach -t gemini دوباره متصل شوید.

آیا اجرای Gemini CLI روی یک سرور عملیاتی (production) امن است؟

فقط با احتیاط؛ زیرا یک عامل (agent) با دسترسی shell می‌تواند هر کاری که کاربرِ اجراکننده انجام می‌دهد را تکرار کند. آن را به عنوان یک کاربر اختصاصی و بدون امتیاز (unprivileged) بدون sudo اجرا کنید، اعتبارنامه‌های عملیاتی را روی آن ماشین قرار ندهید، از تأیید خودکار --yolo اجتناب کنید و از --sandbox (Docker یا Podman) برای ایزوله کردن فراخوانی ابزارها از میزبان استفاده کنید. حسابی که برنامه تحت آن اجرا می‌شود، از هر پرچمی که تنظیم می‌کنید اهمیت بیشتری دارد.

آیا نیاز است پورت‌های فایروال را برای Gemini CLI باز کنم؟

خیر. این یک کلاینت است که تماس‌های HTTPS خروجی به APIهای Google برقرار می‌کند، بنابراین به پورت خروجی 443 نیاز دارد اما هیچ پورت ورودی لازم ندارد. اگر از تونل OAuth استفاده می‌کنید، پورت callback ثابت‌شده (مثلاً 8085) روی localhost قرار دارد و از طریق SSH forward شما در دسترس است، نه به عنوان یک پورت ورودی باز. پورت‌های ورودی را بسته نگه دارید.

#gemini-cli#node#tmux#headless#ai#vps