Cara Menjalankan Gemini CLI di VPS Tanpa Desktop
Jalankan Gemini CLI di VPS headless dengan Node terbaru, instalasi global tanpa sudo, autentikasi API key tanpa browser, dan tmux agar tugas tetap berjalan.
Yang Anda bangun
Gemini CLI yang selalu aktif pada server milik Anda, dapat diakses melalui SSH, dan menjalankan tugas agen yang panjang setelah laptop ditutup. Instalasinya terdiri dari tiga perintah. Bagian yang membutuhkan pekerjaan adalah semua hal yang mengasumsikan adanya desktop: CLI Google ingin membuka browser untuk melakukan login, sedangkan server Anda tidak memilikinya. Karena itu, sebagian besar panduan ini membahas metode headless, Node versi terbaru yang tidak disediakan oleh distro, instalasi npm global tanpa root, autentikasi tanpa browser menggunakan API key yang tidak tersimpan dalam riwayat shell, serta tmux agar sesi SSH yang terputus tidak menghentikan tugas yang sedang berjalan.
Gemini CLI adalah program Node open-source (Apache-2.0) (@google/gemini-cli) yang berkomunikasi dengan model Gemini milik Google dan dapat membaca serta menulis file, menjalankan perintah shell, dan menggunakan tools di direktori kerja. Pada VPS, program ini menjadi agen kecil yang selalu tersedia dan dapat dibiarkan bekerja. Karena itu, akun yang digunakan untuk menjalankannya serta kredensial yang tersimpan di server lebih penting daripada satu pengaturan tertentu di sini.
Prasyarat dan kendala yang perlu diketahui
- VPS KVM Ubuntu 24.04 baru dengan akses root atau sudo. Paket KVM apa pun dapat digunakan; CLI ini ringan dan hanya menggunakan RAM beberapa ratus MB saat tidak aktif.
- Node.js 20 atau yang lebih baru. Ini adalah batas versi minimum yang wajib dipenuhi. Paket dari distro masih di bawah versi tersebut; lihat bagian berikutnya.
- HTTPS keluar (port 443) ke API Google. Tidak diperlukan port masuk; ini adalah client, bukan server, sehingga Anda tidak perlu membuka celah pada firewall.
- Metode autentikasi yang tidak memerlukan browser di server: Gemini API key dari Google AI Studio, atau SSH tunnel ke browser pada komputer Anda sendiri. Metode API key dapat digunakan untuk script dan eksekusi tanpa pengawasan.
- Docker atau Podman, hanya jika Anda ingin menggunakan isolasi
--sandbox. Opsional; pembahasannya ada menjelang akhir.
Kendala yang sering terlewat: alur login pertama kali gemini yang sederhana dirancang untuk desktop. Alur ini mencoba membuka browser dan, pada server headless, dapat gagal atau memberikan link yang tidak berfungsi. Tentukan metode autentikasi sebelum memulai.
Node: paket distro terlalu lama
Ubuntu 24.04 menyediakan Node 18.19.1 di repositorinya sendiri, bersama npm 9.2.0. package.json Gemini CLI menyatakan engines: { node: ">=20" }, dan secara default npm tidak langsung menghentikan proses ketika versinya tidak cocok. npm tetap menginstal paket, lalu mencetak peringatan yang menunjukkan perbedaan versi tersebut:
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 }Jika peringatan itu diabaikan, CLI berjalan pada runtime yang tidak didukung. CLI dapat berperilaku tidak semestinya atau mengalami crash saat mencapai API Node 20+ yang seharusnya tersedia. Node 18 juga telah mencapai akhir masa dukungan pada April 2025, sehingga tetap bukan pilihan yang dapat digunakan. Instal LTS terbaru sebelum menginstal CLI. Ada dua pilihan yang sesuai: NodeSource, yaitu repositori apt bertanda tangan yang berlaku untuk seluruh sistem, atau nvm, yaitu version manager per pengguna. Pilih salah satu.
NodeSource, jika Node ingin tersedia untuk semua pengguna di 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 --versionnode --version harus menampilkan v20.x atau lebih tinggi. v24.x adalah LTS aktif saat ini. Periksa halaman NodeSource untuk mendapatkan skrip penyiapan terbaru. Nilai setup_24.x pada URL adalah bagian yang harus diubah ketika LTS yang lebih baru dirilis.
nvm, jika Node ingin tetap berada di direktori home satu pengguna dan tidak pernah dikelola dengan sudo:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc
nvm install --lts
node --versionNilai v0.40.1 pada URL tersebut adalah versi terbaru saat panduan ini ditulis. Periksa README nvm untuk mengetahui rilis terbaru, lalu ganti versinya sebelum menjalankan perintah tersebut. nvm memiliki keunggulan nyata untuk kebutuhan ini: nvm menginstal Node dan paket globalnya di bawah ~/.nvm, sehingga masalah izin saat instalasi global pada bagian berikutnya tidak akan terjadi. Jika memilih nvm, Anda dapat melewati langkah pengaturan npm-prefix.
Instal CLI tanpa sudo npm -g
Perintah yang terlihat mudah adalah sudo npm install -g @google/gemini-cli. Jangan gunakan perintah tersebut. Prefix global yang dimiliki root menyebabkan error izin pada setiap instalasi berikutnya dan meninggalkan file milik root di cache npm Anda. File tersebut dapat menimbulkan masalah berbulan-bulan kemudian. Jalankan npm install -g biasa (tanpa sudo) pada Node sistem, dan Anda akan mendapatkan kegagalan lain:
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 sedang mencoba menulis ke /usr/lib, yang tidak dapat diakses untuk ditulis oleh pengguna Anda. Solusinya bukan sudo. Arahkan prefix global npm ke direktori home Anda agar instalasi global ditempatkan di lokasi yang Anda miliki:
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, bukan ~/.profile, digunakan dengan sengaja. tmux, yang akan Anda gunakan untuk menjalankan CLI dua bagian setelah ini, memulai shell non-login yang membaca ~/.bashrc dan melewati ~/.profile. Karena itu, baris PATH di file yang salah membuat gemini tidak terlihat tepat di tempat yang Anda perlukan. gemini --version yang menampilkan nomor versi adalah satu-satunya pengujian yang diperlukan. Jika yang muncul adalah gemini: command not found, ekspor PATH Anda tidak diterapkan. Lihat bagian tentang mode kegagalan. Pada nvm, lewati seluruh baris prefix karena nvm sudah memasang paket global di bawah direktori home Anda.
Jika sebelumnya Anda pernah menjalankan sudo npm dan sekarang melihat Your cache folder contains root-owned files, perbaiki satu kali dengan sudo chown -R $(id -u):$(id -g) ~/.npm.
Masalah autentikasi headless dan cara mengatasinya
Jalankan gemini secara interaktif untuk pertama kalinya. Perintah ini akan menawarkan login dengan akun Google Anda. Pada desktop, perintah ini membuka tab browser. Pada VPS headless tidak ada browser. Karena itu, alurnya akan mencetak URL localhost yang harus Anda buka atau langsung gagal dengan pesan seperti:
Failed to open browser. Please visit the following URL to authorize:
https://accounts.google.com/o/oauth2/v2/auth?...&redirect_uri=http://localhost:PORTMasalahnya adalah redirect_uri=http://localhost:PORT. Meskipun Anda membuka URL tersebut di laptop dan menyetujuinya, Google mengarahkan kembali ke http://localhost:PORT, yaitu localhost pada server. Port tersebut tidak dapat dijangkau oleh laptop Anda. Login tidak pernah selesai.
Ada dua cara yang tepat untuk mengatasinya.
Cara pertama adalah menggunakan API key. Ini merupakan pilihan default yang tepat untuk server. Buat key di Google AI Studio (aistudio.google.com), lalu berikan key tersebut ke CLI sebagai environment variable. CLI membaca GEMINI_API_KEY dan sepenuhnya melewati alur browser. Selanjutnya, pastikan key tidak masuk ke history atau file yang dapat dibaca semua pengguna. Jangan ketik export GEMINI_API_KEY=AIza... pada prompt karena perintah tersebut menyimpan key dalam ~/.bash_history sebagai teks biasa. Jangan pula menaruhnya di file yang dapat dibaca pengguna lain. Tulis key ke file dengan mode 600 yang dibaca shell saat memulai:
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 berarti hanya user Anda yang dapat membaca file tersebut. Pastikan key masuk ke environment dengan printenv GEMINI_API_KEY. Jika perintah itu tidak mencetak apa pun, CLI akan kembali ke alur browser dan gagal. CLI juga membaca file .env di ~/.gemini/ jika Anda memilih susunan tersebut. Aturan yang sama berlaku, jadi chmod 600 ~/.gemini/.env.
Cara kedua mempertahankan login dengan akun Google pribadi, termasuk free tier-nya, dengan meneruskan callback OAuth kembali ke laptop. Masalahnya, server loopback CLI menggunakan port acak pada setiap proses. Karena itu, tidak ada port tetap yang dapat diteruskan sebelum Anda menetapkannya dengan environment variable OAUTH_CALLBACK_PORT. Setelah itu, teruskan port yang sama persis:
# 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
geminiCLI tidak dapat membuka browser, sehingga CLI mencetak URL autentikasi. Buka URL tersebut di browser laptop Anda dan setujui aksesnya. Saat Google mengarahkan kembali ke http://localhost:8085/..., SSH forward meneruskannya ke server loopback pada VPS dan login selesai. Jika port tidak ditetapkan, setiap proses akan menggunakan port acak baru. Akibatnya, ssh -L yang disiapkan sebelumnya tidak dapat menangkap koneksi tersebut. Cara ini berfungsi, tetapi Anda harus berada di depan browser. Karena itu, cara ini tidak cocok untuk script. Untuk proses yang dibiarkan berjalan, gunakan API key.
Untuk Vertex AI atau project Google Cloud, bukan AI Studio, tetapkan GOOGLE_API_KEY bersama GOOGLE_GENAI_USE_VERTEXAI=true. Gunakan GOOGLE_CLOUD_PROJECT untuk lisensi Code Assist. Terapkan aturan environment variable yang sama dan gunakan file dengan mode 600 yang sama.
Jalankan di dalam tmux agar sesi SSH yang terputus tidak menghentikannya
Proses gemini yang Anda jalankan langsung dari shell SSH merupakan proses anak dari shell tersebut. Jika koneksi terputus, laptop ditutup, Wi-Fi terputus, atau batas waktu idle tercapai, sshd membongkar pseudo-terminal, shell menerima SIGHUP, lalu meneruskannya ke CLI. Tugas yang sudah berjalan selama sepuluh menit saat mengedit file ikut berhenti, dan setelah tersambung kembali tidak ada proses yang dapat dilanjutkan.
tmux mengatasi masalah ini dengan mengambil alih shell, bukan sebaliknya seperti pada sshd. Polanya sama seperti menjalankan agen coding AI pada VPS jarak jauh di dalam tmux, dan cara kerjanya juga sama di sini:
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 geminitmux new -A -s gemini menyambungkan Anda ke sesi bernama gemini jika sesi tersebut ada, dan membuatnya jika belum ada. Karena itu, perintah ini dapat dijalankan setiap kali selesai login. Shell di dalamnya dimiliki oleh server tmux yang terlepas, bukan oleh sesi SSH Anda, sehingga koneksi yang terputus tidak menghentikan CLI. Sambungkan kembali, lakukan attach, dan Anda kembali ke scrollback yang sama. Jika Anda menjalankan beberapa sesi agen pada satu server, gunakan satu sesi tmux untuk setiap agen. Dalam konteks ini, sesi-sesi tersebut tidak dapat saling berkomunikasi, berbeda dengan Claude Code, yang memungkinkan satu sesi meneruskan teks ke sesi lain pada VPS yang sama. Karena itu, jalankan setiap tugas Gemini secara independen atau koordinasikan melalui file di disk.
Untuk eksekusi noninteraktif berbasis skrip, Gemini CLI memiliki mode headless: gemini -p "summarise the failing tests in this repo" mencetak jawaban lalu keluar, sedangkan --output-format json menghasilkan output yang dapat dibaca mesin untuk diteruskan ke proses lain. Mode headless dengan API key cocok digunakan dalam sesi tmux yang menjalankan tugas batch panjang atau dipanggil dari entri cron. Namun, ada satu hal penting: cron tidak memuat file login apa pun. Karena itu, berikan GEMINI_API_KEY tersendiri pada baris crontab tersebut, atau minta perintah memuat ~/.gemini_env. Jika tidak, CLI akan kembali menggunakan alur browser dan gagal.
Sandboxing dan izin pada server yang juga menjalankan layanan produksi
Agen yang memiliki akses shell sama dengan akses shell. Gemini CLI dapat menjalankan perintah. Secara default, Gemini CLI meminta konfirmasi sebelum menjalankan perintah yang berisiko. Namun, pengguna sering memilih --yolo (menyetujui setiap pemanggilan tool secara otomatis). Setelah itu, agen dapat menghapus file, melakukan push ke git, atau mengakses layanan internal dengan hak akses penuh dari pengguna yang menjalankannya. Pada server yang juga menjalankan layanan produksi, dampaknya nyata dan bukan sekadar kemungkinan teoretis.
Tiga kontrol berikut diurutkan berdasarkan besarnya manfaat:
- Jalankan sebagai pengguna khusus tanpa hak istimewa. Jangan gunakan root dan jangan jadikan pengguna tersebut anggota
sudo. Buat penggunaagentdengan home directory sendiri, lalu instal Node dan CLI di sana. Dengan demikian, instruksi yang salah dipahami tetap terbatas pada akun tersebut. Ini adalah keputusan dengan manfaat keamanan paling besar. - Jauhkan kredensial produksi dari server. Jangan simpan
~/.aws/credentialsproduksi, jangan salin.envdari lingkungan produksi, dan jangan gunakan password database yang memiliki akses tulis ke data atau layanan penting. Berikan kredensial staging atau kredensial read-only. - Gunakan sandbox bawaan. Jika Docker atau Podman sudah terinstal,
gemini --sandbox(atauGEMINI_SANDBOX=docker) menjalankan pemanggilan tool oleh agen di dalam container yang terisolasi dari filesystem dan jaringan host. Ini bukan pengganti pengguna tanpa hak istimewa, tetapi merupakan lapisan kedua yang kuat ketika VPS yang sama menjalankan layanan penting.
Jika Anda menjalankan Gemini CLI bersama tool self-hosted lain, misalnya MCP server yang menyediakan tool untuk agen pada VPS yang sama, anggap setiap kemampuan tambahan sebagai perluasan permukaan yang dapat dijangkau agen. Batasi token yang diberikan hanya untuk satu tugas tertentu.
Kuota, biaya, dan jalur autentikasi yang dipilih
Jalur autentikasi menentukan cara penagihan Anda. Akun Google pribadi (jalur OAuth) menggunakan tier gratis Gemini Code Assist, dengan batas nyata per menit dan per hari. Jika batas tersebut terlampaui, permintaan akan menghasilkan error rate limit sampai jendela waktunya di-reset. API key dari AI Studio dapat menggunakan tier gratis atau ditagihkan, bergantung pada project. API key yang ditagihkan meningkatkan batas dan mengenakan biaya berdasarkan token. Autentikasi Vertex dan project Cloud ditagihkan melalui Google Cloud.
Ada dua catatan praktis. Agent tanpa pengawasan yang berjalan dalam loop dapat menghabiskan kuota dengan cepat, jadi pantau beberapa kali pertama sebelum mempercayakannya ke cron job. Jika alasan Anda menggunakan model di sisi server adalah privasi atau inferensi tanpa meteran, bukan model yang di-host Google, gunakan alat yang berbeda: self-hosting LLM open source dengan Ollama pada VPS menyimpan bobot model dan prompt di server Anda sendiri, dengan konsekuensi harus menjalankan model yang jauh lebih kecil daripada Gemini.
Menjaga agar tetap diperbarui
Gemini CLI sering merilis pembaruan. Karena Anda menginstalnya ke prefix milik pengguna, pembaruan tidak pernah memerlukan sudo:
npm install -g @google/gemini-cli@latest
gemini --versionTersedia beberapa channel rilis: @latest adalah versi stabil, @preview adalah pratinjau mingguan, dan @nightly adalah versi paling mutakhir. Tetapkan ke @latest untuk apa pun yang Anda andalkan. Di nvm, paket global disimpan di bawah versi Node yang aktif. Jadi, setelah nvm use untuk berganti versi Node, Anda mungkin perlu menginstal ulang CLI. Baca catatan rilis daripada mengejar setiap patch.
Mode kegagalan, dengan string yang tepat
npm WARN EBADENGINE Unsupported engine ... required: { node: '>=20' }, kemudian CLI mengalami crash saat runtime. Node terlalu lama, yaitu versi 18.19.1 dari distro, yang juga sudah melewati akhir masa dukungan. Instal Node 20+ dari NodeSource atau nvm, konfirmasikan dengan node --version, dan jika beberapa Node terinstal, periksa apakah which node mengarah ke versi baru, bukan /usr/bin/node.
npm error code EACCES / permission denied, mkdir '/usr/lib/node_modules/...'. Instalasi global dilakukan pada prefix milik root. Jangan gunakan sudo, tetapkan npm config set prefix ~/.npm-global, tambahkan ~/.npm-global/bin ke PATH, lalu instal ulang sebagai pengguna biasa. Jika sudo npm sebelumnya membuat file cache milik root (Your cache folder contains root-owned files), jalankan sudo chown -R $(id -u):$(id -g) ~/.npm.
Failed to open browser, login yang macet, atau redirect_uri=http://localhost:PORT yang tidak dapat Anda akses. Alur OAuth memerlukan browser yang tidak tersedia di server, dan callback localhost-nya mengarah ke server, bukan laptop Anda. Gunakan jalur API key (GEMINI_API_KEY), atau tetapkan OAUTH_CALLBACK_PORT, teruskan melalui SSH dengan ssh -L, lalu buka URL tersebut secara lokal.
Proses menghilang saat koneksi SSH terputus. Anda menjalankan gemini langsung dari shell SSH, sehingga proses tersebut menjadi child dari shell itu dan berhenti bersama pty saat koneksi terputus. Tidak ada yang dapat dipulihkan. Mulai setiap sesi dengan tmux new -A -s gemini, lalu jalankan CLI di dalamnya.
Autentikasi tetap gagal meskipun key sudah ditetapkan, CLI kembali ke pemilih autentikasi, atau sebuah request mengembalikan API key not valid dengan HTTP 400. Key tidak tersedia di environment yang dilihat CLI. Konfirmasikan dengan printenv GEMINI_API_KEY; jika kosong, ~/.gemini_env Anda tidak pernah di-source. Periksa apakah baris tersebut ada di ~/.bashrc, yang dibaca oleh shell interaktif, termasuk tmux, tetapi tidak oleh cron dan shell non-interaktif lainnya. Spasi atau tanda kutip yang tidak semestinya di dalam nilai key juga menghasilkan API key not valid.
429 / RESOURCE_EXHAUSTED / pesan rate limit. Anda telah mencapai kuota untuk tier yang digunakan oleh autentikasi Anda. Tunggu hingga periode kuota direset, kurangi kecepatan agent, atau gunakan API key berbayar. Agent yang terjebak dalam loop retry akan terus mencapai batas ini. Hentikan agent tersebut dan periksa aktivitasnya.
FAQ
Bagaimana cara melakukan autentikasi Gemini CLI pada server headless?
Gunakan API key, bukan login browser. Buat key di Google AI Studio, simpan di file dengan mode-600 yang di-source oleh shell Anda (export GEMINI_API_KEY=...), lalu CLI akan melewati seluruh alur browser OAuth. Jika Anda secara khusus menginginkan free tier akun pribadi, tetapkan port loopback dengan OAUTH_CALLBACK_PORT=8085, teruskan port tersebut kembali ke laptop dengan ssh -L 8085:localhost:8085 user@server, lalu buka URL yang dicetak secara lokal. Namun, cara ini mengharuskan Anda berada di depan browser, sehingga tidak cocok untuk script.
Mengapa instalasi global npm meminta sudo, dan bagaimana cara menghindarinya?
Karena prefix global default npm adalah /usr/lib/node_modules, yang tidak dapat ditulisi oleh user Anda, sehingga npm install -g biasa gagal dengan EACCES. Solusi yang salah adalah sudo npm -g, karena akan meninggalkan file milik root yang kemudian menyebabkan instalasi berikutnya gagal. Solusi yang benar adalah mengarahkan prefix ke home Anda (npm config set prefix ~/.npm-global) dan menambahkan bin ke PATH, atau menggunakan nvm, yang secara otomatis menginstal package global di home Anda.
Bagaimana cara menjaga Gemini CLI tetap berjalan setelah saya disconnect?
Jalankan di dalam tmux. Proses yang dimulai dari shell SSH akan berhenti saat koneksi terputus karena proses tersebut merupakan child dari shell itu; tmux menjalankan shell di bawah server detached yang tetap hidup setelah disconnect. Gunakan tmux new -A -s gemini, jalankan gemini di dalamnya, lakukan detach dengan Ctrl-b d, lalu lakukan reattach nanti dengan tmux attach -t gemini.
Apakah aman menjalankan Gemini CLI pada server production?
Hanya jika dilakukan dengan hati-hati, karena agent dengan akses shell dapat melakukan apa pun yang dapat dilakukan oleh user yang menjalankannya. Jalankan sebagai user khusus tanpa hak istimewa dan tanpa sudo, jangan simpan credential production di mesin tersebut, hindari persetujuan otomatis --yolo, dan gunakan --sandbox (Docker atau Podman) untuk mengisolasi pemanggilan tool dari host. Account yang digunakan untuk menjalankannya lebih penting daripada flag tunggal apa pun yang Anda tetapkan.
Apakah saya perlu membuka port firewall untuk Gemini CLI?
Tidak. Gemini CLI adalah client yang melakukan panggilan HTTPS keluar ke API Google, sehingga memerlukan port keluar 443, tetapi tidak memerlukan port masuk. Jika Anda menggunakan tunnel OAuth, port callback yang ditetapkan, misalnya 8085, berada di localhost dan diakses melalui SSH forward, bukan melalui port masuk yang terbuka. Tetap batasi akses masuk.