SSD Nodes Learn Hosting plans →
Guias Matt ConnorPor Matt Connor

Como rodar o Gemini CLI em um VPS sem interface gráfica

Aprenda a rodar o Gemini CLI em um VPS headless: Node atual, instalação global npm sem sudo, autenticação por API key e tmux contra quedas do SSH.

O que você vai criar

Um Gemini CLI sempre ativo num servidor que controla, acessível por SSH, a executar tarefas longas de agentes que continuam a trabalhar depois de fechar o portátil. A instalação resume-se a três comandos. O trabalho está no que pressupõe um desktop: a CLI da Google tenta abrir um navegador para iniciar sessão, mas o servidor não tem nenhum. Por isso, a maior parte deste guia aborda o procedimento sem interface gráfica, uma versão atual do Node que a distribuição não fornece, uma instalação global do npm que não requer root, a autenticação sem navegador com uma chave de API mantida fora do histórico da shell e o tmux, para que uma sessão SSH interrompida não termine uma tarefa em execução.

O Gemini CLI é um programa Node de código aberto (Apache-2.0) (@google/gemini-cli) que comunica com os modelos Gemini da Google e pode ler e escrever ficheiros, executar comandos da shell e utilizar ferramentas no diretório de trabalho. Num VPS, é um agente pequeno e sempre disponível que pode deixar a trabalhar. Por isso, a conta usada para o executar e as credenciais armazenadas no servidor são mais importantes do que qualquer definição isolada deste guia.

Pré-requisitos e limitações importantes

  • Um VPS KVM Ubuntu 24.04 novo com root ou sudo. Qualquer plano KVM funciona; a CLI é leve e usa algumas centenas de MB de RAM em repouso.
  • Node.js 20 ou mais recente. Este é o único requisito mínimo de versão rígido, e o pacote da distribuição é inferior a ele; consulte a próxima seção. O Node 20 chegou ao fim da vida útil em April 30, 2026, portanto instale o 24.
  • HTTPS de saída (porta 443) para as APIs do Google. Não são necessárias portas de entrada; este é um cliente, não um servidor, portanto não é necessário abrir uma exceção no firewall.
  • Uma forma de autenticação que não exija um browser no servidor: uma API key paga do Gemini obtida no Google AI Studio ou o login do Google, que, num servidor headless, solicita que você cole um código de volta no terminal. O caminho da API key é o adequado para scripts e execuções sem supervisão.
  • Docker ou Podman, apenas se você quiser o isolamento --sandbox. É opcional e será abordado perto do fim.

O problema que atualmente apanha toda a gente está na conta, não no browser. O Google anunciou em May 19, 2026 que, a partir de June 18, 2026, o Gemini CLI deixaria de atender solicitações de assinantes do Google AI Pro e Ultra e de qualquer pessoa que o utilizasse gratuitamente, encaminhando esses utilizadores para o seu substituto, Antigravity CLI (agy). O Gemini CLI continua a funcionar com API keys pagas do Gemini, API keys da Gemini Enterprise Agent Platform e uma licença Gemini Code Assist Standard ou Enterprise da organização. Escolha o caminho de autenticação antes de começar.

Node: o pacote da distribuição é demasiado antigo

O Ubuntu 24.04 disponibiliza o Node 18.19.1 nos próprios repositórios, juntamente com o npm 9.2.0. O package.json do Gemini CLI declara engines: { node: ">=20" }, mas, por predefinição, o npm não interrompe a instalação quando encontra uma versão incompatível. Instala na mesma e apresenta um aviso que indica a diferença:

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 }

Se ignorar esse aviso, o CLI será executado num runtime não suportado. Poderá comportar-se de forma incorreta ou falhar assim que utilizar uma API do Node 20 ou posterior que espera encontrar. O Node 18 também chegou ao fim da vida útil em abril de 2025, pelo que não é uma solução viável. Instale uma versão LTS atual antes de instalar o CLI. Existem duas opções corretas: NodeSource, um repositório apt assinado e disponível para todo o sistema, ou nvm, um gestor de versões por utilizador. Escolha uma.

NodeSource, se quiser disponibilizar o Node a todos os utilizadores do sistema:

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 deve apresentar v20.x ou superior para satisfazer os requisitos do CLI. No entanto, o Node 20 chegou ao fim da vida útil em 30 de abril de 2026, pelo que deve escolher v24.x, a versão LTS ativa atual. Está previsto que o Node 26 se torne a versão LTS ativa em 28 de outubro de 2026. Consulte a página do NodeSource para obter o script de configuração atual. O setup_24.x no URL é o valor que deve atualizar quando for lançada uma versão LTS mais recente.

nvm, se preferir manter o Node no diretório pessoal de um único utilizador e nunca o modificar com sudo:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc
nvm install --lts
node --version

O v0.40.1 nesse URL era a versão atual quando este texto foi escrito. Consulte o README do nvm para obter a versão mais recente e substitua a versão no URL antes de executar o comando. O nvm tem uma vantagem importante neste caso: instala o Node e os respetivos pacotes globais em ~/.nvm, pelo que o problema de permissões da instalação global descrito na secção seguinte não ocorre. Se escolher nvm, pode ignorar o passo de configuração do prefixo do npm.

Instale a CLI sem sudo npm -g

O comando tentador é sudo npm install -g @google/gemini-cli. Não o execute. Um prefixo global pertencente a root causa erros de permissões em todas as instalações seguintes e deixa ficheiros pertencentes a root na cache do npm, o que pode causar problemas meses mais tarde. Se executar um npm install -g simples, sem sudo, contra um Node do sistema, terá o outro erro:

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'

O npm está a tentar escrever em /usr/lib, onde o seu utilizador não tem permissões. A correção não é usar sudo. Defina o prefixo global do npm para o seu diretório pessoal, para que as instalações globais sejam feitas num local que lhe pertence:

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, e não ~/.profile, é intencional. O tmux, que executará a CLI dentro de duas secções, inicia uma shell que não é de login. Essa shell lê ~/.bashrc e ignora ~/.profile. Por isso, uma linha PATH no ficheiro errado deixa gemini invisível exatamente onde precisa dele. gemini --version imprimir um número de versão é o teste completo. Se obtiver gemini: command not found, a exportação de PATH não foi aplicada. Consulte as formas de falha. No nvm, ignore totalmente as linhas do prefixo. O nvm já instala os pacotes globais no seu diretório pessoal.

Se executou sudo npm anteriormente e agora vê Your cache folder contains root-owned files, corrija o problema uma vez com sudo chown -R $(id -u):$(id -g) ~/.npm.

O problema de autenticação sem interface e como ultrapassá-lo

Execute gemini interativamente pela primeira vez. O comando oferece a opção de iniciar sessão com a sua conta Google. Num desktop, abre um separador do navegador. Num VPS Linux sem interface gráfica, a CLI verifica primeiro se existe um display. Quando nenhum de DISPLAY, WAYLAND_DISPLAY ou MIR_SOCKET está definido, não tenta iniciar um navegador. Mostra uma ligação de início de sessão e espera que cole um código:

Please visit the following URL to authorize the application:

https://accounts.google.com/o/oauth2/v2/auth?...

Enter the authorization code:

Esse fluxo funciona através de SSH simples, mas exige que esteja junto de um navegador sempre que o utiliza. Desde June 18, 2026, também só permite iniciar sessão se a sua conta Google estiver entre as contas ainda suportadas pelo Gemini CLI.

Existem duas formas diretas de resolver o problema.

A primeira é utilizar uma chave de API. É a opção predefinida correta para um servidor. Crie uma chave no Google AI Studio (aistudio.google.com), num projeto com a faturação ativada, porque o Gemini CLI já não disponibiliza utilização gratuita. Depois, forneça a chave à CLI através de uma variável de ambiente. A CLI lê GEMINI_API_KEY e ignora completamente o fluxo do navegador. Falta evitar que a chave fique no histórico ou em ficheiros legíveis por outros utilizadores. Não introduza export GEMINI_API_KEY=AIza... diretamente na prompt. O valor ficará gravado em ~/.bash_history em texto simples. Também não o coloque num ficheiro que outros utilizadores possam ler. Grave-o num ficheiro com modo 600 que a shell carregue no arranque:

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 significa que apenas o seu utilizador pode ler o ficheiro. Confirme que a chave chegou ao ambiente com printenv GEMINI_API_KEY. Se o comando não mostrar nada, a CLI volta ao seletor de autenticação em vez de utilizar a chave. A CLI também lê um ficheiro .env em ~/.gemini/, se preferir essa estrutura. A mesma regra aplica-se nesse caso: chmod 600 ~/.gemini/.env.

A segunda opção é utilizar o próprio início de sessão Google. Num servidor sem interface, este método não precisa de túnel nem de uma porta aberta. Desde June 18, 2026, é sobretudo útil para uma licença Gemini Code Assist Standard ou Enterprise de uma organização. Nesse caso, defina também GOOGLE_CLOUD_PROJECT. As contas pessoais gratuitas e as subscrições Google AI Pro ou Ultra já não são suportadas. Inicie a CLI numa sessão SSH normal e escolha Sign in with Google:

gemini

Copie o URL apresentado para o navegador do seu portátil e autorize o acesso. O Google redireciona para https://codeassist.google.com/authcode, que mostra um código de autorização. Cole o código na prompt Enter the authorization code: do VPS. O início de sessão é concluído. Nada no servidor fica à espera de um callback. Por isso, não existe nenhuma porta a fixar nem ssh -L a configurar. OAUTH_CALLBACK_PORT só é relevante para o fluxo de loopback que a CLI utiliza quando encontra um display. Se estabelecer a ligação com encaminhamento X11 (ssh -X), DISPLAY fica definido e a CLI utiliza esse fluxo de loopback. Nesse caso, o redirecionamento é feito para http://127.0.0.1:PORT/oauth2callback no servidor. Execute NO_BROWSER=true gemini para forçar o fluxo de colar um código. Funciona, mas exige que esteja junto de um navegador. Por isso, não é adequado para scripts. Para qualquer processo que deixe em execução, utilize a chave de API.

Para utilizar Vertex AI ou um projeto Google Cloud em vez do AI Studio, defina GOOGLE_API_KEY juntamente com GOOGLE_GENAI_USE_VERTEXAI=true, ou GOOGLE_CLOUD_PROJECT para uma licença Code Assist. Aplique as mesmas regras às variáveis de ambiente e utilize o mesmo ficheiro com modo 600.

Execute-o dentro do tmux para que uma sessão SSH interrompida não o termine

Um processo gemini iniciado diretamente a partir da shell SSH é filho dessa shell. Se perder a ligação, fechar o portátil, a rede Wi-Fi for interrompida ou ocorrer um tempo limite de inatividade, o sshd encerra o pseudo-terminal, a shell recebe SIGHUP e, por sua vez, termina a CLI. Uma tarefa que já esteja há dez minutos a editar ficheiros termina com ela. Ao voltar a ligar-se, não há nenhum processo que possa recuperar.

O tmux resolve isto assumindo a gestão da shell, em vez de a sshd gerir. É o mesmo padrão usado para executar um agente de programação com IA num VPS remoto dentro do tmux, e funciona da mesma forma neste caso:

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 liga-se a uma sessão chamada gemini se ela existir e cria-a se não existir. Por isso, é o único comando a executar imediatamente depois de cada login. A shell dentro da sessão pertence ao servidor tmux destacado, não à sessão SSH. Assim, se a ligação for interrompida, a CLI continua a funcionar. Volte a ligar-se, anexe-se à sessão e terá novamente o mesmo histórico do terminal. Se acabar por executar várias sessões de agentes na mesma máquina, uma por sessão tmux, elas não têm aqui forma de comunicar entre si. Isto é diferente do Claude Code, em que uma sessão pode enviar texto para outra no mesmo VPS. Mantenha cada tarefa do Gemini independente ou coordene-as através de ficheiros no disco.

Para execuções não interativas e baseadas em scripts, o Gemini CLI tem um modo headless: gemini -p "summarise the failing tests in this repo" apresenta uma resposta e termina, enquanto --output-format json produz uma saída legível por máquinas para encaminhar para outro processo. O modo headless com uma chave de API é exatamente o que deve usar dentro de uma sessão tmux que executa uma tarefa batch longa ou a partir de uma entrada do cron. Há uma ressalva: uma tarefa do cron não carrega nenhum dos seus ficheiros de login. Por isso, forneça à linha do crontab o seu próprio GEMINI_API_KEY ou faça o comando carregar ~/.gemini_env. Caso contrário, a execução falha por falta de credenciais.

Sandboxing e permissões num servidor que também executa produção

Um agente com acesso à shell tem acesso à shell. O Gemini CLI pode executar comandos e, por predefinição, pede confirmação antes de cada comando potencialmente perigoso. No entanto, é comum usar --yolo (aprovação automática de todas as chamadas de ferramentas). Nesse caso, o agente pode apagar ficheiros, fazer push para o git ou aceder a serviços internos com todas as permissões do utilizador que o executa. Num servidor que também executa produção, isto representa uma superfície de impacto real, não um risco hipotético.

Três controlos, por ordem do benefício que proporcionam:

  • Execute-o com um utilizador dedicado e sem privilégios. Não use root nem um membro de sudo. Crie um utilizador agent com o seu próprio diretório home, instale o Node e a CLI nesse utilizador e mantenha uma instrução interpretada incorretamente confinada a essa conta. Esta é a decisão isolada com maior impacto na segurança.
  • Mantenha as credenciais de produção fora do servidor. Não instale ~/.aws/credentials de produção, não copie .env do ambiente de produção e não use uma palavra-passe de base de dados com acesso de escrita a dados importantes. Forneça uma credencial de staging ou apenas de leitura.
  • Use o sandbox integrado. Com Docker ou Podman instalado, gemini --sandbox (ou GEMINI_SANDBOX=docker) executa as chamadas de ferramentas do agente dentro de um contentor que monta apenas o diretório do projeto atual, e não o resto do sistema de ficheiros do host. Isto não substitui o utilizador sem privilégios, mas é uma segunda camada forte quando o mesmo VPS executa trabalho real.

Se executar o Gemini CLI junto de outras ferramentas self-hosted, como um servidor MCP que expõe ferramentas ao agente no mesmo VPS, trate cada capacidade adicional como mais uma superfície a que o agente pode aceder e limite os tokens fornecidos exatamente a uma tarefa.

Cota, custo e o caminho de autenticação escolhido

O caminho de autenticação determina como é feita a cobrança e, desde 18 de junho de 2026, também determina se o serviço é disponibilizado. A partir dessa data, segundo o anúncio da Google, o Gemini CLI deixou de atender pedidos de subscritores do Google AI Pro e Ultra e de qualquer pessoa que o utilizasse gratuitamente. Isso inclui o nível gratuito de contas pessoais e as chaves de API não faturadas. O serviço continua disponível através de chaves de API pagas do Gemini e de chaves de API do Gemini Enterprise Agent Platform, cobradas por token, e para organizações com uma licença Gemini Code Assist Standard ou Enterprise ou com outro tipo de acesso ao Google Cloud, faturado através do Google Cloud. Cada nível continua a ter limites por minuto e por dia. Quando esses limites são excedidos, os pedidos devolvem um erro de limitação de taxa até à reposição da janela.

Há duas notas práticas. Um agente sem supervisão, executado num ciclo, pode consumir a cota rapidamente. Monitorize-o nas primeiras execuções antes de confiar nele para um cron job. Se o motivo para utilizar um modelo no servidor for a privacidade ou a inferência sem medição, em vez dos modelos alojados pela Google, trata-se de uma ferramenta diferente. A auto-hospedagem de um LLM aberto com Ollama numa VPS mantém os pesos e os pedidos no seu próprio servidor, mas implica executar um modelo muito menor do que o Gemini.

Mantê-lo atualizado

O Gemini CLI lança versões com frequência. Como foi instalado num prefixo pertencente ao utilizador, as atualizações nunca precisam de sudo:

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

Existem canais de lançamento: @latest é o estável, @preview é a versão de pré-visualização semanal e @nightly é a versão mais recente e instável. Fixe @latest em qualquer ambiente de que dependa. Com nvm, os pacotes globais ficam na versão ativa do Node. Por isso, depois de nvm use para mudar de versão do Node, pode ser necessário reinstalar a CLI. Consulte as notas de lançamento em vez de instalar todas as correções assim que ficam disponíveis.

Modos de falha, com as strings exatas

npm WARN EBADENGINE Unsupported engine ... required: { node: '>=20' } e, depois, o CLI falha em tempo de execução. O Node é demasiado antigo: o da distribuição é o 18.19.1, que também já ultrapassou o fim do suporte. Instale uma versão LTS atual através do NodeSource ou do nvm (o Node 20 cumpre o requisito mínimo do CLI, mas também ficou sem suporte em abril de 2026), confirme com node --version e, se tiver várias versões do Node instaladas, verifique se which node aponta para a nova versão e não para /usr/bin/node.

npm error code EACCES / permission denied, mkdir '/usr/lib/node_modules/...'. Foi feita uma instalação global num prefixo pertencente a root. Não use sudo; defina npm config set prefix ~/.npm-global, coloque ~/.npm-global/bin em PATH e reinstale como o seu utilizador normal. Se um sudo npm anterior tiver deixado ficheiros de cache pertencentes a root (Your cache folder contains root-owned files), execute sudo chown -R $(id -u):$(id -g) ~/.npm.

Failed to open browser ou um redirect_uri que aponta para http://127.0.0.1:PORT, ao qual não consegue aceder. O CLI encontrou uma variável de display, muitas vezes proveniente de ssh -X, e usou o fluxo de loopback, cujo callback chega ao servidor. Execute NO_BROWSER=true gemini para obter o fluxo de colagem de um código ou use o fluxo de chave da API (GEMINI_API_KEY). Numa sessão SSH simples, deverá ver Enter the authorization code:; aprove o URL no navegador do seu portátil e cole o código apresentado pelo Google.

O processo desapareceu quando a sessão SSH foi terminada. Executou gemini diretamente a partir da shell SSH, por isso era um processo filho dessa shell e terminou com o pty quando a ligação foi desligada. Não há nada para recuperar. Inicie todas as sessões com tmux new -A -s gemini e execute o CLI dentro dela.

A autenticação continua a falhar com a chave definida, o CLI volta ao seletor de autenticação ou um pedido devolve API key not valid com HTTP 400. A chave não está no ambiente que o CLI vê. Confirme com printenv GEMINI_API_KEY; se estiver vazio, o seu ~/.gemini_env nunca foi carregado. Verifique se a linha está em ~/.bashrc, que é lido pelas shells interativas, incluindo o tmux, mas não por cron nem por outras shells não interativas. Um espaço ou aspas indevidos dentro do valor da chave também produzem API key not valid.

429 / RESOURCE_EXHAUSTED / uma mensagem de limite de pedidos. Atingiu a quota do nível de autenticação utilizado. Aguarde até a janela ser reposta, reduza a velocidade do agente ou mude para uma chave de API faturada. Um agente preso num ciclo de novas tentativas continua a atingir este limite; pare-o e verifique o que está a fazer.

FAQ

Como autentico o Gemini CLI num servidor sem interface gráfica?

Use uma chave de API paga, não o início de sessão pelo navegador. Crie uma chave no Google AI Studio num projeto faturado, guarde-a num ficheiro com permissões mode-600 que a sua shell carregue (export GEMINI_API_KEY=...) e o CLI ignora completamente o fluxo OAuth no navegador. Se iniciar sessão com uma conta Google, por exemplo, com uma licença Code Assist Standard ou Enterprise, o CLI numa máquina sem interface gráfica mostra um URL; abra-o no seu portátil, autorize o acesso e cole o código apresentado pela Google no prompt Enter the authorization code:. Não é necessário fixar nenhuma porta nem criar um túnel, mas precisa de estar presente num navegador, por isso não é adequado para scripts. As contas pessoais gratuitas deixaram de ser suportadas pelo Gemini CLI em June 18, 2026.

Porque é que a instalação global do npm pede sudo e como evito isso?

Porque o prefixo global predefinido do npm é /usr/lib/node_modules, onde o seu utilizador não pode escrever, por isso um npm install -g simples falha com EACCES. A correção errada é sudo npm -g, que deixa ficheiros pertencentes a root e causa falhas nas instalações seguintes. A correção certa é apontar o prefixo para o seu diretório pessoal (npm config set prefix ~/.npm-global) e adicionar o respetivo bin a PATH, ou usar nvm, que instala automaticamente os pacotes globais no seu diretório pessoal.

Como mantenho o Gemini CLI em execução depois de desligar?

Execute-o dentro do tmux. Um processo iniciado a partir da sua shell SSH termina quando a ligação cai, porque é um processo filho dessa shell; o tmux executa a shell num servidor separado que continua ativo depois da desligação. Use tmux new -A -s gemini, execute gemini dentro da sessão, desanexe com Ctrl-b d e volte a ligá-la mais tarde com tmux attach -t gemini.

É seguro executar o Gemini CLI num servidor de produção?

Apenas com cuidado, porque um agente com acesso à shell pode fazer tudo o que o utilizador com que é executado pode fazer. Execute-o com um utilizador dedicado sem privilégios e sem sudo, não mantenha credenciais de produção na máquina, evite --yolo para aprovação automática e use --sandbox (Docker ou Podman) para isolar as chamadas de ferramentas do host. A conta com que o agente é executado é mais importante do que qualquer opção individual que defina.

Preciso de abrir portas na firewall para o Gemini CLI?

Não. É um cliente que faz chamadas HTTPS de saída para as APIs da Google, por isso precisa da porta de saída 443, mas não de portas de entrada. O início de sessão Google numa máquina sem interface gráfica também não precisa de nenhuma porta: cole um código de volta no terminal em vez de receber um callback no servidor. Mantenha as ligações de entrada bloqueadas.

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