SSD Nodes Learn Hosting plans →
Gidsen Matt ConnorDoor Matt Connor · Bijgewerkt 2026-08-28

Gemini CLI installeren op een headless VPS

Leer hoe u de Gemini CLI op een headless VPS draait zonder browser. Wij behandelen Node-versiebeheer, rootvrije npm-installaties, API-key authenticatie en tmux voor sessiebehoud.

Wat u bouwt

Een altijd actieve Gemini CLI op een server in uw eigen beheer, bereikbaar via SSH, die langlopende agent-taken uitvoert die doorgaan nadat u uw laptop afsluit. De installatie bestaat uit drie commando's. Het werk zit in alles wat uitgaat van een desktopomgeving: de CLI van Google wil een browser openen voor de aanmelding, maar uw server heeft er geen. Daarom beslaat het grootste deel van deze handleiding het headless-traject: een actuele Node-versie die uw distributie niet standaard levert, een globale npm-installatie waarvoor geen root-rechten nodig zijn, authenticatie zonder browser met een API-key die u buiten uw shell-geschiedenis houdt, en tmux zodat een verbroken SSH-sessie geen actieve taak beëindigt.

Gemini CLI is een open-source (Apache-2.0) Node-programma (@google/gemini-cli) dat communiceert met de Gemini-modellen van Google. Het kan bestanden lezen en schrijven, shell-commando's uitvoeren en tools aansturen in de werkmap. Op een VPS fungeert het als een kleine, altijd beschikbare agent die u aan het werk kunt laten. Daarom zijn het account waaronder het programma draait en de inloggegevens op de server belangrijker dan enige individuele instelling in deze handleiding.

Vereisten en de belangrijkste valkuilen

  • Een verse Ubuntu 24.04 KVM VPS met root- of sudo-toegang. Elk KVM-abonnement volstaat; de CLI zelf is licht en verbruikt in ruststand slechts enkele honderden MB aan RAM.
  • Node.js 20 of nieuwer. Dit is de harde ondergrens voor de versie; het pakket in de distributie is ouder, zie de volgende sectie.
  • Uitgaand HTTPS-verkeer (poort 443) naar de API's van Google. Er zijn geen inkomende poorten nodig; dit is een client, geen server, dus u hoeft geen firewall-poorten te openen.
  • Een authenticatiemethode waarvoor geen browser op de server vereist is: ofwel een Gemini API-sleutel van Google AI Studio, of een SSH-tunnel naar een browser op uw eigen machine. De methode met de API-sleutel is geschikt voor scripts en onbeheerde processen.
  • Docker of Podman, alleen als u de --sandbox isolatie wenst. Optioneel, wordt aan het einde behandeld.

De valkuil waar iedereen in trapt: de gebruiksvriendelijke gemini inlogprocedure voor de eerste keer is ontworpen voor een desktopomgeving. Deze probeert een browser te openen en op een headless systeem resulteert dit in een foutmelding of een link die niet werkt. Bepaal het authenticatiepad voordat u begint.

Opmerking: het distributiepakket is te oud

Ubuntu 24.04 levert Node 18.19.1 in de eigen repositories, gekoppeld aan npm 9.2.0. De package.json van de Gemini CLI declareert engines: { node: ">=20" }, en npm blokkeert een mismatch standaard niet; het installeert het pakket alsnog en toont een waarschuwing die het verschil benoemt:

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 }

Negeert u deze waarschuwing, dan draait de CLI op een niet-ondersteunde runtime. Hierdoor vertoont de applicatie onvoorspelbaar gedrag of crasht deze zodra een Node 20+ API wordt aangeroepen die niet aanwezig is. Node 18 bereikte bovendien in april 2025 het einde van de levenscyclus (EOL), dus dit is in beide gevallen een doodlopend spoor. Installeer een actuele LTS-versie voordat u de CLI installeert. Er zijn twee schone methoden: NodeSource (een systeembrede ondertekende apt-repository) of nvm (een versiebeheerder per gebruiker). Kies één van beide.

NodeSource, als u wilt dat Node beschikbaar is voor elke gebruiker op de server:

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 moet v20.x of hoger weergeven; v24.x is de huidige actieve LTS. Controleer de NodeSource-pagina voor het meest recente installatiescript; de setup_24.x in de URL is het versienummer dat u moet aanpassen zodra er een nieuwere LTS beschikbaar komt.

nvm, als u Node liever binnen de home-directory van één gebruiker houdt en nooit met sudo wilt werken:

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

De v0.40.1 in die URL was actueel op het moment van schrijven; controleer de README van nvm voor de laatste release en vervang de versie voordat u het script uitvoert. nvm biedt voor deze taak een groot voordeel: het installeert Node en de bijbehorende globale pakketten onder ~/.nvm, waardoor het probleem met rechten bij globale installaties uit de volgende sectie simpelweg niet optreedt. Als u voor de nvm-methode kiest, kunt u de stap met npm-prefix overslaan.

De CLI installeren zonder sudo npm -g

Het verleidelijke commando is sudo npm install -g @google/gemini-cli. Doe dit niet. Een globale prefix die eigendom is van root veroorzaakt bij elke latere installatie rechtenfouten en laat bestanden in uw npm-cache achter die eigendom zijn van root; dit zal u over enkele maanden problemen opleveren. Voer een standaard (zonder sudo) npm install -g uit op een systeem-Node en u krijgt de andere foutmelding:

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'

Dit is npm dat probeert te schrijven naar /usr/lib, waar uw gebruiker geen rechten voor heeft. De oplossing is niet sudo, maar om de globale prefix van npm naar uw home-directory te wijzen, zodat globale installaties op een locatie terechtkomen waar u eigenaar van bent:

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, en niet ~/.profile, is een bewuste keuze: tmux, waarbinnen u over twee secties de CLI zult uitvoeren, start een non-login shell die ~/.bashrc leest en ~/.profile overslaat. Een PATH-regel in het verkeerde bestand zorgt er dus voor dat gemini onzichtbaar is op precies de plek waar u het nodig heeft. Als gemini --version een versienummer print, is de test geslaagd. Krijgt u in plaats daarvan gemini: command not found, dan is uw PATH-export niet doorgevoerd; raadpleeg de foutmodi. Bij nvm kunt u de prefix-regels volledig overslaan: deze installeert globale pakketten al in uw home-directory.

Als u op een eerder moment sudo npm heeft uitgevoerd en nu Your cache folder contains root-owned files ziet, herstel dit dan eenmalig met sudo chown -R $(id -u):$(id -g) ~/.npm.

Het probleem met headless authenticatie en hoe dit te omzeilen

Voer gemini de eerste keer interactief uit en het programma biedt aan u in te loggen met uw Google-account. Op een desktop opent dit een browsertabblad. Op een headless VPS is er geen browser, dus de procedure print ofwel een localhost-URL die u moet openen, of faalt direct met een melding zoals:

Failed to open browser. Please visit the following URL to authorize:
https://accounts.google.com/o/oauth2/v2/auth?...&redirect_uri=http://localhost:PORT

De valkuil is de redirect_uri=http://localhost:PORT. Zelfs als u die URL op uw laptop opent en goedkeurt, stuurt Google u door naar http://localhost:PORT, localhost op de server, een poort die vanaf uw laptop niet bereikbaar is. De inlogprocedure wordt nooit voltooid.

Er zijn twee correcte manieren om dit op te lossen.

De eerste is een API-sleutel, wat de juiste standaard is voor een server. Maak een sleutel aan in Google AI Studio (aistudio.google.com) en geef deze aan de CLI mee als omgevingsvariabele; het programma leest GEMINI_API_KEY en slaat de browserprocedure volledig over. Nu het gedeelte over "houd het uit de geschiedenis en bestanden die voor iedereen leesbaar zijn". Typ niet export GEMINI_API_KEY=AIza... bij de prompt, want dit komt in leesbare tekst terecht in ~/.bash_history, en plaats de sleutel niet in een bestand dat anderen kunnen lezen. Schrijf de sleutel naar een bestand met modus 600 dat de shell bij het opstarten inlaadt:

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 betekent dat alleen uw gebruiker het bestand kan lezen. Controleer of de sleutel in de omgeving is geladen met printenv GEMINI_API_KEY; als dit niets print, valt de CLI terug op de browserprocedure en faalt deze. Het programma leest ook een .env-bestand in ~/.gemini/ als u die indeling verkiest, met dezelfde regel, dus chmod 600 ~/.gemini/.env.

De tweede manier behoudt het inloggen met een persoonlijk Google-account (en het bijbehorende gratis abonnement) door de OAuth-callback terug te tunnelen naar uw laptop. Het addertje onder het gras is dat de loopback-server van de CLI bij elke uitvoering een willekeurige poort kiest, dus er is niets stabiels om door te sturen tenzij u dit eerst vastzet met de omgevingsvariabele OAUTH_CALLBACK_PORT, en vervolgens exact die poort doorstuurt:

# 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

De CLI kan geen browser openen, dus print het de auth-URL; open deze in de browser op uw laptop, keur het goed, en wanneer Google doorstuurt naar http://localhost:8085/..., brengt de SSH-forwarding dit naar de loopback-server op de VPS en wordt het inloggen voltooid. Laat u de poort niet vastzetten, dan komt deze bij elke uitvoering op een nieuwe willekeurige poort terecht, die geen enkele vooraf ingestelde ssh -L kan opvangen. Het werkt, maar vereist dat u achter een browser zit, dus het is ongeschikt voor scripts. Gebruik voor alles wat u op de achtergrond laat draaien de API-sleutel.

Stel voor Vertex AI of een Google Cloud-project in plaats van AI Studio GOOGLE_API_KEY in, samen met GOOGLE_GENAI_USE_VERTEXAI=true, of GOOGLE_CLOUD_PROJECT voor een Code Assist-licentie, met dezelfde discipline voor omgevingsvariabelen en hetzelfde bestand met modus 600.

Voer het uit in tmux zodat een verbroken SSH-sessie het proces niet beëindigt

Een gemini-proces dat u rechtstreeks vanuit uw SSH-shell start, is een kindproces van die shell. Bij een verbroken verbinding, een dichtgeklapte laptop, wegvallende wifi of een idle-timeout, breekt sshd de pseudo-terminal af. De shell ontvangt een SIGHUP en beëindigt vervolgens de CLI-sessie. Een taak die tien minuten bezig is met het bewerken van bestanden sterft hiermee, en bij het opnieuw verbinden is er geen proces meer om te herstellen.

tmux lost dit op door de shell te beheren in plaats van dat sshd dit doet. Dit is hetzelfde patroon als het draaien van een AI-coding agent op een externe VPS binnen tmux, en het werkt hier identiek:

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 koppelt aan een sessie genaamd gemini als deze bestaat, en maakt deze aan als dat niet zo is. Dit is dus het enige commando dat u direct na elke login hoeft uit te voeren. De shell binnenin behoort toe aan de losgekoppelde tmux-server, niet aan uw SSH-sessie. Het verbreken van de verbinding laat de CLI dus gewoon doorwerken. Verbind opnieuw, koppel aan de sessie, en u bent terug bij dezelfde scrollback. Als u meerdere agentsessies op één machine draait, één per tmux-sessie, kunnen deze onderling niet communiceren, in tegenstelling tot Claude Code, waarbij één sessie tekst kan doorgeven aan een andere op dezelfde VPS. Houd elke Gemini-taak daarom onafhankelijk of coördineer ze via bestanden op de schijf.

Voor niet-interactieve, gescripte runs heeft de Gemini CLI een headless-modus: gemini -p "summarise the failing tests in this repo" print een antwoord en sluit af, en --output-format json geeft machineleesbare uitvoer om naar elders te pipen. Headless-modus met een API-sleutel is precies wat u nodig heeft binnen een tmux-sessie die een lange batchtaak uitvoert, of aangestuurd vanuit een cron-entry, met één kanttekening: een cron-job laadt geen van uw login-bestanden. Geef de crontab-regel daarom zijn eigen GEMINI_API_KEY (of laat het commando ~/.gemini_env sourcen), anders valt de CLI terug op de browser-flow en mislukt het proces.

Sandboxing en rechten op een server die ook productieomgevingen draait

Een agent met shell-toegang is een shell. De Gemini CLI kan commando's uitvoeren en vraagt standaard om bevestiging bij elk risicovol commando, maar gebruikers grijpen vaak naar --yolo (automatisch goedkeuren van elke tool-aanroep). Hierdoor kan de agent bestanden verwijderen, pushen naar git of interne services benaderen met de volledige bevoegdheden van de gebruiker waaronder deze draait. Op een server die ook productieomgevingen draait, is dit een reëel risico met grote gevolgen, geen hypothetisch scenario.

Drie beheersmaatregelen, gerangschikt op effectiviteit:

  • Draai de agent als een toegewezen, niet-geprivilegieerde gebruiker. Gebruik niet root en geen lid van sudo. Maak een agent-gebruiker aan met een eigen home-directory, installeer Node en de CLI daar, en een verkeerd geïnterpreteerd commando blijft beperkt tot dat account. Dit is de belangrijkste beslissing voor de veiligheid.
  • Houd productie-inloggegevens van de server af. Geen productie-~/.aws/credentials, geen .env die vanaf productie is gekopieerd, en geen databasewachtwoord met schrijfrechten voor kritieke systemen. Geef de agent inloggegevens voor een staging-omgeving of alleen-lezen toegang.
  • Gebruik de ingebouwde sandbox. Met Docker of Podman geïnstalleerd, voert gemini --sandbox (of GEMINI_SANDBOX=docker) de tool-aanroepen van de agent uit binnen een container die is geïsoleerd van het bestandssysteem en het netwerk van de host. Dit is geen vervanging voor een niet-geprivilegieerde gebruiker, maar het is een sterke tweede laag wanneer dezelfde VPS ook daadwerkelijk productiewerk verricht.

Als u Gemini CLI naast andere zelfgehoste tools draait, zoals een MCP-server die tools aan de agent op dezelfde VPS blootstelt, beschouw elke toegevoegde functionaliteit dan als een groter aanvalsoppervlak dat de agent kan bereiken. Beperk de tokens die aan de agent worden verstrekt tot exact één taak.

Quota, kosten en de gekozen authenticatieroute

De authenticatieroute bepaalt hoe u wordt gefactureerd. Een persoonlijk Google-account (de OAuth-route) maakt gebruik van de gratis Gemini Code Assist-laag, met strikte limieten per minuut en per dag; bij overschrijding retourneren verzoeken een rate-limit-fout totdat het venster wordt gereset. Een API-sleutel uit AI Studio kan afhankelijk van het project onder de gratis laag vallen of worden gefactureerd; een gefactureerde sleutel verhoogt de limieten en brengt kosten per token in rekening. Vertex- en Cloud-projectauthenticatie worden gefactureerd via Google Cloud.

Twee praktische opmerkingen. Een onbeheerde agent in een lus kan snel quota verbruiken, dus houd deze de eerste keren in de gaten voordat u deze toevertrouwt aan een cron job. En als uw reden voor een server-side model privacy of onbeperkte inferentie is in plaats van de gehoste modellen van Google, dan is dat een andere tool; het zelf hosten van een open LLM met Ollama op een VPS houdt de gewichten en de prompts op uw eigen machine, ten koste van het draaien van een aanzienlijk kleiner model dan Gemini.

Updates bijhouden

Gemini CLI brengt regelmatig nieuwe versies uit. Omdat u de tool in een prefix onder uw eigen gebruikersaccount heeft geïnstalleerd, is voor updates nooit sudo vereist:

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

Er zijn verschillende releasekanalen: @latest is de stabiele versie, @preview is de wekelijkse preview, @nightly is de meest recente ontwikkelversie; gebruik @latest voor alles waar u op vertrouwt. Bij nvm bevinden globale pakketten zich onder de actieve Node-versie. Na het uitvoeren van nvm use om van Node-versie te wisselen, moet u de CLI mogelijk opnieuw installeren. Lees de release notes in plaats van elke patch direct te installeren.

Foutmodi, met de exacte strings

npm WARN EBADENGINE Unsupported engine ... required: { node: '>=20' }, gevolgd door een crash van de CLI tijdens runtime. De Node-versie is te oud; de distributie gebruikt 18.19.1, wat tevens het einde van de levensduur heeft bereikt. Installeer Node 20+ via NodeSource of nvm, bevestig dit met node --version, en als u meerdere Node-versies heeft geïnstalleerd, controleer dan of which node naar de nieuwe versie wijst en niet naar /usr/bin/node.

npm error code EACCES / permission denied, mkdir '/usr/lib/node_modules/...'. Een globale installatie in een prefix die eigendom is van root. Gebruik hiervoor geen sudo, stel npm config set prefix ~/.npm-global in, plaats ~/.npm-global/bin in PATH en installeer opnieuw als uw normale gebruiker. Als een eerdere sudo npm cachebestanden heeft achtergelaten die eigendom zijn van root (Your cache folder contains root-owned files), voer dan sudo chown -R $(id -u):$(id -g) ~/.npm uit.

Failed to open browser, een login die blijft hangen, of een redirect_uri=http://localhost:PORT die u niet kunt bereiken. De OAuth-flow vereist een browser die de server niet heeft, en de localhost-callback wijst naar de server in plaats van naar uw laptop. Gebruik het API-key-pad (GEMINI_API_KEY), of pin OAUTH_CALLBACK_PORT, stuur dit door via SSH met ssh -L en open de URL lokaal.

Het proces verdween toen de SSH-verbinding werd verbroken. U voerde gemini direct uit vanuit de SSH-shell; het proces was een kind van die shell en stierf samen met de pty bij het verbreken van de verbinding. Er is niets te herstellen. Start elke sessie met tmux new -A -s gemini en voer de CLI daarbinnen uit.

Authenticatie mislukt nog steeds met de ingestelde key, de CLI keert terug naar de authenticatie-kiezer, of een verzoek retourneert API key not valid met HTTP 400. De key bevindt zich niet in de omgeving die de CLI ziet. Bevestig dit met printenv GEMINI_API_KEY; als deze leeg is, werd uw ~/.gemini_env nooit geladen. Controleer of de regel in ~/.bashrc staat, wat interactieve shells (inclusief tmux) inlezen, maar cron en andere niet-interactieve shells niet. Een extra spatie of aanhalingsteken in de waarde van de key veroorzaakt eveneens API key not valid.

429 / RESOURCE_EXHAUSTED / een rate-limit melding. U heeft het quotum bereikt voor de tier die uw authenticatie gebruikt. Wacht tot het venster is gereset, vertraag de agent of stap over naar een betaalde API-key. Een agent die vastzit in een retry-loop blijft dit quotum overschrijden; stop de agent en controleer wat deze uitvoert.

FAQ

Hoe authenticeer ik de Gemini CLI op een headless server?

Gebruik een API-sleutel in plaats van de browser-login. Maak een sleutel aan in Google AI Studio, sla deze op in een bestand met modus 600 dat uw shell inlaadt (export GEMINI_API_KEY=...), waarna de CLI de OAuth-browserflow volledig overslaat. Als u specifiek gebruik wilt maken van de gratis laag voor persoonlijke accounts, zet dan de loopback-poort vast met OAUTH_CALLBACK_PORT=8085, stuur deze door naar uw laptop met ssh -L 8085:localhost:8085 user@server en open de weergegeven URL lokaal. Dit vereist echter dat u fysiek toegang heeft tot een browser, waardoor het ongeschikt is voor scripts.

Waarom vereist een globale npm-installatie sudo en hoe vermijd ik dit?

Omdat het standaard globale voorvoegsel van npm /usr/lib/node_modules is, waar uw gebruiker niet naar kan schrijven. Daarom faalt een standaard npm install -g met EACCES. De onjuiste oplossing is sudo npm -g, omdat dit bestanden achterlaat die eigendom zijn van root, wat latere installaties verstoort. De juiste oplossing is om het voorvoegsel naar uw home-directory te wijzen (npm config set prefix ~/.npm-global) en de bijbehorende bin toe te voegen aan PATH, of gebruik te maken van nvm, dat globale pakketten automatisch onder uw home-directory installeert.

Hoe houd ik de Gemini CLI actief nadat ik de verbinding verbreek?

Voer het uit binnen tmux. Een proces dat vanuit uw SSH-shell is gestart, stopt zodra de verbinding wordt verbroken omdat het een kindproces van die shell is; tmux voert de shell uit onder een losgekoppelde server die de verbreking overleeft. Gebruik tmux new -A -s gemini, voer gemini uit, koppel los met Ctrl-b d en koppel later opnieuw met tmux attach -t gemini.

Is het veilig om de Gemini CLI op een productieserver te draaien?

Alleen met de nodige voorzichtigheid, aangezien een agent met shell-toegang alles kan doen wat de gebruiker waaronder deze draait ook kan. Voer het uit als een toegewezen gebruiker zonder privileges en zonder sudo-rechten, bewaar geen productie-inloggegevens op de machine, vermijd --yolo voor automatische goedkeuring en gebruik --sandbox (Docker of Podman) om tool-aanroepen te isoleren van de host. Het account waaronder het proces draait is belangrijker dan welke individuele vlag dan ook.

Moet ik firewall-poorten openen voor de Gemini CLI?

Nee. Het is een client die uitgaande HTTPS-aanroepen doet naar de API's van Google; hiervoor is uitgaande poort 443 nodig, maar geen inkomende poorten. Als u de OAuth-tunnel gebruikt, bevindt de vastgezette callback-poort (bijvoorbeeld 8085) zich op localhost en wordt deze bereikt via uw SSH-forward, niet via een open inkomende poort. Houd inkomend verkeer geblokkeerd.

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