SSD Nodes Learn Hosting plans →
Посібники Matt ConnorВід Matt Connor · Оновлено 2026-08-28

Gemini CLI на VPS без GUI: встановлення та запуск

Запустіть Gemini CLI на headless VPS: актуальний Node, глобальне npm-встановлення без sudo, вхід за API key без браузера та tmux після розриву SSH.

Що ви створюєте

Gemini CLI, який постійно працює на вашому сервері, доступний через SSH і виконує тривалі завдання агента навіть після закриття ноутбука. Встановлення складається з трьох команд. Складність пов’язана з усім, що передбачає наявність графічного робочого середовища: CLI від Google намагається відкрити браузер для входу, а на сервері браузера немає. Тому більша частина цього посібника присвячена роботі без графічного інтерфейсу, встановленню актуальної версії Node, якої немає в репозиторіях дистрибутива, глобальному встановленню npm без root, автентифікації без браузера за допомогою API key, який не потрапляє до історії shell, а також tmux, щоб розірване SSH-з’єднання не зупинило поточне завдання.

Gemini CLI — це open-source програма на Node за ліцензією Apache-2.0 (@google/gemini-cli), яка взаємодіє з моделями Gemini від Google, може читати й записувати файли, виконувати shell-команди та використовувати інструменти в робочому каталозі. На VPS це невеликий агент, доступний постійно й здатний працювати без нагляду. Тому обліковий запис, від імені якого він запускається, і облікові дані, що зберігаються на сервері, важливіші за будь-який окремий параметр у цьому посібнику.

Передумови та важливі обмеження

  • Чистий Ubuntu 24.04 KVM VPS із root або sudo. Підійде будь-який KVM plan; сам CLI потребує небагато ресурсів — після запуску достатньо кількох сотень MB RAM.
  • Node.js 20 або новішої версії. Це єдина жорстка вимога до версії. Пакет у дистрибутиві має нижчу версію. Див. наступний розділ.
  • Вихідний HTTPS-трафік (порт 443) до API Google. Вхідні порти не потрібні. Це клієнт, а не сервер, тому відкривати окремий порт у firewall не потрібно.
  • Спосіб автентифікації, який не потребує браузера на сервері: Gemini API key із Google AI Studio або SSH tunnel до браузера на вашому комп’ютері. Варіант із API key підходить для скриптів і запусків без участі користувача.
  • Docker або Podman, лише якщо потрібна ізоляція --sandbox. Це необов’язково. Її розглянуто ближче до кінця.

Обмеження, яке найчастіше створює проблеми: зручний flow першого входу gemini розрахований на desktop. Він намагається відкрити браузер і на headless-сервері або завершується помилкою, або надає посилання, яке не працює. Визначте спосіб автентифікації до початку роботи.

Node: пакет дистрибутива надто старий

Ubuntu 24.04 постачається з Node 18.19.1 у власних репозиторіях разом із npm 9.2.0. Gemini CLI у package.json оголошує 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+, яке має бути доступним. Node 18 також досяг кінця життєвого циклу у квітні 2025 року, тому цей варіант у будь-якому разі непридатний. Встановіть актуальну LTS-версію до встановлення CLI. Є 2 коректні варіанти: NodeSource — системний підписаний apt-репозиторій — або nvm — version manager для окремого користувача. Виберіть один із них.

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 script. Значення setup_24.x в URL — це рядок, який потрібно змінити, коли з’явиться нова LTS-версія.

nvm, якщо ви хочете зберігати Node у домашньому каталозі одного користувача та ніколи не керувати ним через 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, щоб дізнатися про останній release, і замініть версію перед запуском команди. nvm має важливу перевагу для цього завдання: він встановлює Node і його глобальні пакети в ~/.nvm. Тому проблема з правами під час глобального встановлення з наступного розділу просто не виникає. Якщо ви обрали nvm, крок із налаштуванням npm-prefix можна пропустити.

Встановлення CLI без sudo npm -g

Спокуслива команда — sudo npm install -g @google/gemini-cli. Не використовуйте її. Глобальний prefix, власником якого є root, спричинятиме помилки доступу під час кожного наступного встановлення. Він також залишає файли, власником яких є root, у кеші npm. Через кілька місяців це може спричинити проблеми. Якщо виконати звичайний (без 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, а налаштувати глобальний prefix npm на каталог у вашому домашньому каталозі. Тоді глобальні пакети встановлюватимуться в каталог, власником якого ви є:

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 є навмисним. Через два розділи ви запускатимете CLI у tmux. Він запускає non-login shell, який читає ~/.bashrc і пропускає ~/.profile. Тому рядок PATH у неправильному файлі залишить gemini невидимим саме там, де він потрібен. Виведення gemini --version з номером версії є повною перевіркою. Якщо натомість ви отримали gemini: command not found, експорт PATH не застосувався. Дивіться способи усунення помилок. У nvm повністю пропустіть рядки з prefix: nvm уже встановлює глобальні пакети у ваш домашній каталог.

Якщо раніше ви виконували sudo npm і тепер бачите Your cache folder contains root-owned files, один раз виправте це за допомогою sudo chown -R $(id -u):$(id -g) ~/.npm.

Проблема автентифікації без графічного інтерфейсу та способи її вирішення

Перший запуск gemini виконується в інтерактивному режимі, і програма пропонує увійти за допомогою облікового запису Google. На настільному комп’ютері відкривається вкладка браузера. На headless VPS браузера немає, тому процес або виводить 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 через змінну середовища. CLI читає GEMINI_API_KEY і повністю пропускає автентифікацію через браузер. Тепер потрібно подбати, щоб ключ не потрапив в історію команд або у файли, доступні всім користувачам. Не вводьте export GEMINI_API_KEY=AIza... у prompt: значення буде збережено у ~/.bash_history у відкритому вигляді. Також не записуйте ключ у файл, який можуть прочитати інші користувачі. Запишіть його у файл із правами доступу mode-600, який shell завантажує під час запуску:

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 повернеться до автентифікації через браузер, і процес завершиться помилкою. CLI також читає файл .env у ~/.gemini/, якщо ви віддаєте перевагу такій структурі. Правило те саме: chmod 600 ~/.gemini/.env.

Другий спосіб зберігає вхід через особистий обліковий запис Google і доступ до його free tier, перенаправляючи OAuth callback назад на ноутбук через SSH tunnel. Проблема в тому, що loopback server 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 не може відкрити браузер, тому виводить auth URL. Відкрийте його у браузері на ноутбуці та підтвердьте вхід. Коли Google перенаправить запит на http://localhost:8085/..., SSH forward передасть його loopback server на VPS, і вхід завершиться. Якщо не зафіксувати порт, під час кожного запуску використовуватиметься новий випадковий порт. Жоден ssh -L, налаштований заздалегідь, не зможе перехопити такий запит. Спосіб працює, але потребує браузера та вашої участі, тому не підходить для скриптів. Для процесів, які мають працювати постійно, використовуйте API key.

Для Vertex AI або Google Cloud project замість AI Studio задайте GOOGLE_API_KEY разом із GOOGLE_GENAI_USE_VERTEXAI=true або GOOGLE_CLOUD_PROJECT для Code Assist licence. Дотримуйтеся тих самих правил для змінних середовища та використовуйте той самий файл із правами mode-600.

Запускайте його всередині tmux, щоб розірваний SSH-сеанс не завершив процес

Процес gemini, запущений безпосередньо з SSH-оболонки, є дочірнім процесом цієї оболонки. Якщо з’єднання розірвалося через закриття ноутбука, втрату Wi-Fi або тайм-аут бездіяльності, sshd закриває псевдотермінал, оболонка отримує SIGHUP і, своєю чергою, завершує роботу CLI. Завдання, яке вже десять хвилин редагувало файли, завершується разом із ним. Після повторного підключення відновити процес уже неможливо.

tmux вирішує цю проблему, оскільки сам керує оболонкою, а не передає керування 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, якщо такий сеанс існує, і створює його, якщо його немає. Тому це єдина команда, яку потрібно виконувати одразу після кожного входу. Оболонка всередині належить від’єднаному серверу tmux, а не вашому SSH-сеансу. Тому розрив з’єднання не зупиняє CLI. Після повторного підключення виконайте attach і поверніться до того самого scrollback. Якщо на одному сервері потрібно запустити кілька сеансів агента, використовуйте окремий сеанс tmux для кожного. У цьому випадку вони не можуть взаємодіяти один з одним, на відміну від Claude Code, де один сеанс може передати текст іншому на тому самому VPS. Тому запускайте кожне завдання Gemini незалежно або координуйте їх через файли на диску.

Для неінтерактивних запусків зі сценаріїв Gemini CLI має headless mode: gemini -p "summarise the failing tests in this repo" виводить відповідь і завершує роботу, а --output-format json передає машинно-читаний результат для подальшого перенаправлення. Headless mode з API key підходить для запуску всередині сеансу tmux, що виконує тривале пакетне завдання, або з cron entry. Є один нюанс: cron job не завантажує жодного з ваших login files. Тому вкажіть у рядку crontab власний GEMINI_API_KEY або змусьте команду завантажити ~/.gemini_env. Інакше CLI перейде до browser flow і завершиться з помилкою.

Ізоляція та права доступу на сервері, який також працює в production

Агент із доступом до shell фактично має доступ до shell. Gemini CLI може виконувати команди. За замовчуванням він запитує підтвердження перед кожною потенційно небезпечною командою. Але користувачі часто вмикають --yolo (автоматичне підтвердження кожного виклику інструмента). Після цього CLI може видаляти файли, виконувати push у git або звертатися до внутрішніх сервісів із повними правами користувача, від імені якого він працює. На сервері, який також обслуговує production, це реальний радіус потенційного впливу, а не гіпотетичний ризик.

Три засоби захисту в порядку їхньої ефективності:

  • Запускайте його від імені окремого непривілейованого користувача. Не від імені root і не від імені користувача, який входить до sudo. Створіть користувача agent з окремим home-каталогом, установіть Node і CLI для цього користувача. Тоді помилково інтерпретована інструкція залишатиметься в межах цього облікового запису. Це найважливіше рішення.
  • Не зберігайте production-облікові дані на сервері. Не використовуйте production ~/.aws/credentials, не копіюйте з production .env і не зберігайте пароль бази даних із правом запису до критичних даних. Надайте облікові дані staging або доступ лише для читання.
  • Використовуйте вбудовану sandbox. Якщо встановлено Docker або Podman, gemini --sandbox (або GEMINI_SANDBOX=docker) виконує виклики інструментів агента всередині контейнера, ізольованого від файлової системи та мережі host. Це не замінює непривілейованого користувача, але є додатковим надійним рівнем захисту, коли той самий VPS виконує реальні робочі завдання.

Якщо ви запускаєте Gemini CLI поруч з іншими self-hosted інструментами, наприклад MCP-сервером, який надає агенту інструменти на тому самому VPS, сприймайте кожну додаткову можливість як розширення поверхні доступу агента. Передавайте йому токени з правами, обмеженими рівно одним завданням.

Квоти, вартість і вибраний спосіб автентифікації

Спосіб автентифікації визначає, як нараховується оплата. Особистий обліковий запис Google (спосіб OAuth) використовує безкоштовний рівень Gemini Code Assist із фактичними лімітами на хвилину та день. Якщо перевищити їх, запити повертатимуть помилку обмеження частоти до завершення відповідного періоду. API key з AI Studio може працювати на безкоштовному рівні або передбачати оплату залежно від проєкту. Платний ключ збільшує ліміти, а оплата нараховується за токени. Автентифікація через Vertex і Cloud project передбачає оплату через Google Cloud.

Важливі два практичні моменти. Агент без нагляду, який працює в циклі, може швидко витратити квоту, тому перші кілька разів контролюйте його роботу, перш ніж додавати до cron job. Якщо ж вам потрібна модель на сервері через вимоги до приватності або для inference без лімітів, а не hosted models від Google, це інший інструмент: self-hosting відкритої LLM за допомогою Ollama на VPS зберігає ваги моделі та промпти на вашому сервері, але потребує запуску значно меншої моделі, ніж Gemini.

Підтримка актуальної версії

Gemini CLI часто випускає нові версії. Оскільки ви встановили його в prefix, власником якого є користувач, для оновлення не потрібен sudo:

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

Доступні такі канали релізів: @latest — стабільний, @preview — щотижнева попередня версія, @nightly — найновіша експериментальна версія. Для всього, від чого залежить ваша робота, зафіксуйте @latest. У nvm глобальні пакети зберігаються в активній версії Node, тому після nvm use для перемикання Node може знадобитися повторно встановити CLI. Читайте примітки до релізів, а не встановлюйте кожен патч без потреби.

Режими відмови з точними рядками

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/...'. Глобальне встановлення виконується в префікс, власником якого є 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-ключем (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 не було завантажено. Перевірте, що рядок додано до ~/.bashrc. Цей файл читають інтерактивні оболонки, зокрема tmux, але його не читають cron та інші неінтерактивні оболонки. Зайвий пробіл або лапки всередині значення ключа також спричиняють API key not valid.

429 / RESOURCE_EXHAUSTED / повідомлення про обмеження частоти запитів. Ви перевищили квоту для рівня, який використовує ваша автентифікація. Дочекайтеся скидання ліміту, зменште швидкість роботи агента або перейдіть на платний API-ключ. Агент, який застряг у циклі повторних спроб, продовжує досягати цього ліміту. Зупиніть його та перевірте, що саме він робить.

FAQ

Як авторизувати Gemini CLI на сервері без графічного інтерфейсу?

Використовуйте API key, а не вхід через браузер. Створіть key у Google AI Studio, збережіть його у файлі з правами 600, який завантажує ваша shell (export GEMINI_API_KEY=...), і CLI повністю пропустить браузерний OAuth flow. Якщо вам потрібен саме безкоштовний тариф для personal account, зафіксуйте loopback port за допомогою OAUTH_CALLBACK_PORT=8085, перешліть його назад на свій ноутбук через ssh -L 8085:localhost:8085 user@server і відкрийте виведену URL-адресу локально. Але для цього потрібно бути присутнім біля браузера, тому такий спосіб не підходить для scripts.

Чому глобальне встановлення npm потребує sudo і як цього уникнути?

Тому що типовий глобальний prefix npm — /usr/lib/node_modules. Ваш користувач не має права запису до цього каталогу, тому звичайна команда npm install -g завершується помилкою EACCES. Неправильне рішення — sudo npm -g. Воно залишає файли, власником яких є root, і через це наступні встановлення завершуються помилками. Правильне рішення — вказати prefix у вашому home-каталозі (npm config set prefix ~/.npm-global) і додати його до PATH за допомогою bin. Інший варіант — використати nvm, який автоматично встановлює global packages у вашому home-каталозі.

Як залишити Gemini CLI запущеним після розриву з’єднання?

Запускайте його всередині tmux. Процес, запущений з вашої SSH shell, завершується після розриву з’єднання, оскільки є дочірнім процесом цієї shell. tmux запускає shell під detached server, який переживає розрив з’єднання. Використайте tmux new -A -s gemini, запустіть усередині нього gemini, від’єднайтеся за допомогою Ctrl-b d, а пізніше повторно під’єднайтеся через tmux attach -t gemini.

Чи безпечно запускати Gemini CLI на production-сервері?

Лише за умови обережного налаштування, оскільки agent із доступом до shell може виконати будь-яку дію, доступну користувачу, від імені якого він працює. Запускайте його від імені окремого unprivileged user без sudo, не зберігайте production credentials на цьому сервері, уникайте автоматичного підтвердження --yolo і використовуйте --sandbox (Docker або Podman), щоб ізолювати виклики інструментів від host. Обліковий запис, від імені якого працює agent, важливіший за будь-який окремий flag.

Чи потрібно відкривати порти firewall для Gemini CLI?

Ні. Це client, який виконує вихідні HTTPS-запити до API Google. Тому йому потрібен вихідний port 443, але вхідні порти не потрібні. Якщо ви використовуєте OAuth tunnel, зафіксований callback port, наприклад 8085, працює на localhost і доступний через ваш SSH forward, а не через відкритий вхідний port. Залишайте вхідні з’єднання заблокованими.

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