SSD Nodes Learn
Panduan Matt ConnorOleh Matt Connor · Dikemas kini 2026-07-24

Cara pasang Gemini CLI pada VPS headless

Panduan pasang Gemini CLI pada VPS tanpa GUI menggunakan Node terkini, npm tanpa sudo, kunci API, dan tmux supaya tugas tidak terhenti jika SSH terputus.

Apa yang anda bina

Satu Gemini CLI yang sentiasa aktif pada pelayan milik anda, boleh dicapai melalui SSH, dan menjalankan tugas ejen jangka panjang yang terus berjalan walaupun selepas anda menutup komputer riba. Proses pemasangan hanya melibatkan tiga arahan. Cabaran utama adalah semua perkara yang memerlukan desktop: CLI Google ingin membuka pelayar untuk log masuk, sedangkan pelayan anda tidak mempunyai pelayar. Oleh itu, sebahagian besar panduan ini menggunakan kaedah headless — versi Node terkini yang tidak disediakan oleh distro anda, pemasangan npm global tanpa memerlukan root, pengesahan tanpa pelayar menggunakan kunci API yang disimpan di luar sejarah shell anda, dan tmux supaya sesi SSH yang terputus tidak menghentikan tugas yang sedang berjalan.

Gemini CLI ialah program Node sumber terbuka (Apache-2.0) (@google/gemini-cli) yang berhubung dengan model Gemini Google. Ia boleh membaca dan menulis fail, menjalankan arahan shell, dan mengendalikan alatan dalam direktori kerja. Pada VPS, ia adalah ejen kecil yang sentiasa tersedia untuk dibiarkan bekerja — sebab itulah akaun yang menjalankan proses tersebut, dan kredensial yang disimpan pada mesin, adalah lebih penting daripada mana-mana tetapan tunggal di sini.

Prasyarat dan masalah teknikal yang nyata

  • VPS Ubuntu 24.04 KVM yang baharu dengan akses root atau sudo. Mana-mana pelan KVM boleh digunakan; CLI ini sangat ringan, hanya menggunakan beberapa ratus MB RAM semasa tidak aktif.
  • Node.js 20 atau versi lebih baharu. Ini adalah had versi minimum yang wajib; pakej distro adalah versi lebih lama — rujuk bahagian seterusnya.
  • HTTPS keluar (port 443) ke API Google. Tiada port masuk diperlukan; ini adalah klien, bukan pelayan, jadi anda tidak perlu membuka sebarang lubang firewall.
  • Kaedah pengesahan yang tidak memerlukan pelayar pada pelayan: sama ada kunci API Gemini daripada Google AI Studio, atau terowong SSH ke pelayar pada mesin anda sendiri. Kaedah kunci API adalah yang terbaik untuk skrip dan pelaksanaan tanpa pemantauan.
  • Docker atau Podman, hanya jika anda mahukan pengasingan --sandbox. Pilihan, dibincangkan di bahagian akhir.

Masalah yang sering mengelirukan pengguna: aliran log masuk gemini kali pertama dibina untuk desktop. Ia cuba membuka pelayar dan, pada sistem headless, ia akan gagal atau memberikan pautan yang tidak berfungsi. Tentukan kaedah pengesahan sebelum anda bermula.

Node: pakej distro terlalu lama

Ubuntu 24.04 membekalkan Node 18.19.1 dalam repositori asalnya, bersama npm 9.2.0. package.json Gemini CLI mengisytiharkan engines: { node: ">=20" }, dan npm tidak menghentikan ralat ketidakpadanan secara lalai — ia tetap memasang dan memaparkan amaran yang menyatakan jurang 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 amaran itu diabaikan, CLI akan berjalan pada runtime yang tidak disokong. Ini menyebabkan ralat atau kegagalan sistem sebaik sahaja ia memerlukan API Node 20+ yang sepatutnya wujud. Node 18 juga telah tamat tempoh sokongan (end-of-life) pada April 2025, jadi ia tidak lagi relevan. Pasang versi LTS terkini sebelum anda memasang CLI. Dua cara yang bersih adalah NodeSource (repositori apt bertandatangan untuk seluruh sistem) atau nvm (pengurus versi untuk setiap pengguna). Pilih salah satu.

NodeSource, jika anda mahu Node tersedia untuk setiap pengguna pada sistem:

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 mesti memaparkan v20.x atau lebih tinggi — v24.x adalah LTS aktif semasa. Semak halaman NodeSource untuk skrip tetapan terkini; setup_24.x dalam URL tersebut adalah bahagian yang perlu dikemas kini apabila LTS baharu dikeluarkan.

nvm, jika anda lebih suka menyimpan Node di dalam folder home pengguna dan tidak mahu menggunakan 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 dalam URL tersebut adalah versi terkini semasa artikel ini ditulis; semak README nvm untuk versi terbaharu dan tukar versi tersebut sebelum menjalankannya. nvm mempunyai kelebihan besar untuk tugasan ini: ia memasang Node dan pakej global di bawah ~/.nvm, jadi masalah keizinan (permission) global-install dalam bahagian seterusnya tidak akan berlaku. Jika anda menggunakan nvm, anda boleh melangkau langkah npm-prefix.

Pasang CLI tanpa sudo npm -g

Perintah sudo npm install -g @google/gemini-cli kelihatan menarik. Jangan gunakannya. Prefix global milik root akan menyebabkan ralat keizinan pada setiap pemasangan seterusnya. Ia juga meninggalkan fail milik root dalam cache npm yang akan menimbulkan masalah beberapa bulan kemudian. Jalankan npm install -g biasa (tanpa sudo) terhadap Node sistem dan anda akan menghadapi 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'

Ini berlaku kerana npm cuba menulis ke dalam /usr/lib, yang tidak boleh diakses oleh pengguna anda. Penyelesaiannya bukan menggunakan sudo — anda perlu menetapkan prefix global npm ke direktori home anda supaya pemasangan global disimpan 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, adalah disengajakan: tmux — yang akan anda gunakan untuk menjalankan CLI dalam dua bahagian lagi — memulakan shell bukan login yang membaca ~/.bashrc dan mengabaikan ~/.profile. Oleh itu, baris PATH dalam fail yang salah akan menyebabkan gemini tidak kelihatan pada tempat yang diperlukan. Ujian utama adalah apabila gemini --version mencetak nombor versi. Jika anda mendapat gemini: command not found, eksport PATH anda tidak berjaya — rujuk mod kegagalan. Jika menggunakan nvm, abaikan baris prefix sepenuhnya: nvm sudah memasang pakej global di bawah direktori home anda.

Jika anda telah menjalankan sudo npm sebelum ini dan kini melihat Your cache folder contains root-owned files, baiki dengan menjalankan sudo chown -R $(id -u):$(id -g) ~/.npm sekali sahaja.

Masalah pengesahan headless, dan cara menyelesaikannya

Jalankan gemini secara interaktif buat kali pertama dan ia akan menawarkan untuk log masuk menggunakan akaun Google anda. Pada komputer desktop, ia akan membuka tab pelayar. Pada VPS headless, tiada pelayar tersedia, jadi proses tersebut sama ada mencetak URL localhost yang perlu anda buka, atau gagal sepenuhnya dengan ralat seperti:

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

Masalahnya adalah redirect_uri=http://localhost:PORT. Walaupun anda membuka URL tersebut pada komputer riba anda dan meluluskannya, Google akan menghalakan semula ke http://localhost:PORT — localhost pada pelayan, iaitu port yang tidak boleh dicapai oleh komputer riba anda. Log masuk tidak akan selesai.

Terdapat dua cara yang berkesan.

Cara pertama ialah menggunakan kunci API, dan ini adalah pilihan lalai yang betul untuk pelayan. Cipta kunci di Google AI Studio (aistudio.google.com) dan berikan kunci tersebut kepada CLI sebagai pemboleh ubah persekitaran; ia akan membaca GEMINI_API_KEY dan melangkau proses pelayar sepenuhnya. Sekarang, bahagian "elakkan daripada disimpan dalam sejarah atau fail yang boleh dibaca umum". Jangan taip export GEMINI_API_KEY=AIza... pada prompt — ia akan disimpan dalam ~/.bash_history dalam bentuk teks biasa, dan jangan letakkannya dalam fail yang boleh dibaca oleh orang lain. Tulis ia ke dalam fail mode-600 yang dimuatkan oleh shell semasa permulaan:

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 bermaksud hanya pengguna anda sahaja yang boleh membaca fail tersebut. Sahkan kunci telah sampai ke persekitaran dengan printenv GEMINI_API_KEY; jika ia tidak mencetak apa-apa, CLI akan kembali ke proses pelayar dan gagal. Ia juga membaca fail .env dalam ~/.gemini/ jika anda lebih suka susun atur tersebut — peraturan yang sama, jadi gunakan chmod 600 ~/.gemini/.env.

Cara kedua adalah mengekalkan log masuk akaun Google peribadi (dan pelan percuma) dengan membuat terowong (tunnelling) OAuth callback kembali ke komputer riba anda. Masalahnya ialah pelayan loopback CLI menggunakan port rawak setiap kali dijalankan, jadi tiada port tetap untuk diteruskan kecuali anda menetapkannya terlebih dahulu dengan pemboleh ubah persekitaran OAUTH_CALLBACK_PORT, kemudian teruskan port tersebut secara tepat:

# 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 tidak boleh membuka pelayar, jadi ia akan mencetak URL pengesahan; buka URL tersebut pada pelayar komputer riba anda, luluskan, dan apabila Google menghalakan semula ke http://localhost:8085/..., terusan SSH akan membawanya ke pelayan loopback pada VPS dan log masuk akan selesai. Jika port tidak ditetapkan, ia akan mendarat pada port rawak baharu setiap kali dijalankan, yang mana mana-mana ssh -L yang ditetapkan lebih awal tidak dapat menangkapnya. Ia berfungsi, tetapi memerlukan anda berada di pelayar, jadi ia tidak sesuai untuk skrip. Untuk apa-apa proses yang dibiarkan berjalan, gunakan kunci API.

Untuk Vertex AI atau projek Google Cloud sebagai ganti AI Studio, tetapkan GOOGLE_API_KEY bersama dengan GOOGLE_GENAI_USE_VERTEXAI=true, atau GOOGLE_CLOUD_PROJECT untuk lesen Code Assist — disiplin pemboleh ubah persekitaran yang sama, fail mode-600 yang sama.

Jalankan di dalam tmux supaya sesi SSH yang terputus tidak menghentikannya

Proses gemini yang anda lancarkan terus dari shell SSH adalah anak kepada shell tersebut. Jika sambungan terputus — komputer riba ditutup, Wi-Fi terputus, atau tamat tempoh idle — sshd akan memusnahkan pseudo-terminal, shell akan menerima SIGHUP, dan ia akan terputus daripada CLI. Tugasan yang sedang berjalan selama sepuluh minit semasa mengedit fail akan mati bersamanya, dan apabila anda menyambung semula, tiada proses yang boleh dipulihkan.

tmux menyelesaikan masalah ini dengan memiliki shell tersebut berbanding sshd memilikinya. Ini adalah corak yang sama seperti menjalankan ejen pengekodan AI pada VPS jauh di dalam tmux, dan ia berfungsi secara identik 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 gemini

tmux new -A -s gemini menyambung ke sesi bernama gemini jika ia wujud dan menciptanya jika tidak, jadi ini adalah satu arahan untuk dijalankan sejurus selepas setiap log masuk. Shell di dalamnya adalah milik pelayan tmux yang terpisah, bukan milik sesi SSH anda, jadi sambungan yang terputus membiarkan CLI terus berfungsi. Sambung semula, sertai semula, dan anda kembali ke skrol yang sama.

Untuk pelaksanaan skrip bukan interaktif, Gemini CLI mempunyai mod headless: gemini -p "summarise the failing tests in this repo" mencetak jawapan dan keluar, manakala --output-format json memberikan output yang boleh dibaca mesin untuk dihantar ke tempat lain. Mod headless dengan kunci API adalah apa yang anda perlukan di dalam sesi tmux yang menjalankan tugasan kelompok yang lama, atau yang dicetuskan daripada entri cron — dengan satu peringatan: tugasan cron tidak memuatkan mana-mana fail log masuk anda, jadi berikan baris crontab anda GEMINI_API_KEY sendiri (atau suruh arahan memuatkan ~/.gemini_env), jika tidak CLI akan kembali ke aliran pelayar dan gagal.

Sandboxing dan keizinan pada sistem yang turut menjalankan produksi

Ejen dengan akses shell adalah sebuah shell. Gemini CLI boleh menjalankan arahan, dan secara lalai ia akan meminta pengesahan sebelum setiap arahan berisiko — tetapi pengguna sering menggunakan --yolo (kelulusan automatik untuk setiap panggilan alatan), dan kemudian ia boleh memadam fail, melakukan push ke git, atau mengakses perkhidmatan dalaman dengan kuasa penuh pengguna yang menjalankannya. Pada sistem yang turut menjalankan produksi, ini adalah radius impak yang nyata, bukan sekadar hipotesis.

Tiga kawalan, mengikut urutan nilai keberkesanannya:

  • Jalankannya sebagai pengguna khas yang tidak mempunyai keistimewaan (unprivileged). Bukan root, bukan ahli sudo. Cipta pengguna agent dengan direktori home sendiri, pasang Node dan CLI di sana, maka arahan yang salah akan kekal terhad pada akaun tersebut. Ini adalah keputusan yang paling bernilai.
  • Jangan simpan kredensial produksi pada sistem tersebut. Tiada ~/.aws/credentials produksi, tiada .env yang disalin dari produksi, tiada kata laluan pangkalan data dengan akses tulis ke mana-mana sistem penting. Berikan kredensial staging atau akses baca sahaja.
  • Gunakan sandbox terbina dalam. Dengan pemasangan Docker atau Podman, gemini --sandbox (atau GEMINI_SANDBOX=docker) menjalankan panggilan alatan ejen di dalam kontena yang terasing daripada sistem fail dan rangkaian hos. Ia bukan pengganti kepada pengguna tanpa keistimewaan, tetapi ia adalah lapisan kedua yang kuat apabila VPS yang sama melakukan kerja sebenar.

Jika anda menjalankan Gemini CLI bersebelahan dengan alatan hos sendiri yang lain — contohnya pelayan MCP yang mendedahkan alatan kepada ejen pada VPS yang sama — anggap setiap keupayaan tambahan sebagai lebih banyak permukaan serangan yang boleh dicapai oleh ejen, dan hadkan token yang diberikan kepadanya hanya untuk satu tugas sahaja.

Kuota, kos, dan laluan pengesahan yang anda pilih

Laluan pengesahan menentukan cara anda dibilkan. Akaun Google peribadi (laluan OAuth) menggunakan pelan Gemini Code Assist percuma, dengan had masa nyata bagi setiap minit dan setiap hari; jika had ini melebihi had, permintaan akan mengembalikan ralat had kadar sehingga tempoh ditetapkan tamat. Kunci API daripada AI Studio boleh menjadi pelan percuma atau dibilkan bergantung pada projek — kunci dibilkan meningkatkan had dan mengenakan caj bagi setiap token. Pengesahan Vertex dan Cloud-project dibilkan melalui Google Cloud.

Dua nota praktikal. Ejen tanpa pengawasan dalam satu gelung boleh menghabiskan kuota dengan cepat, jadi pantau ia pada beberapa kali pertama sebelum anda mempercayainya untuk tugasan cron job. Dan jika sebab anda menggunakan model sebelah pelayan adalah untuk privasi atau inferens tanpa had berbanding model hos Google, itu adalah alatan yang berbeza — hos sendiri LLM sumber terbuka dengan Ollama pada VPS mengekalkan pemberat dan prom pada mesin anda sendiri, dengan kos menjalankan model yang jauh lebih kecil daripada Gemini.

Mengekalkan kemas kini

Gemini CLI kerap dikemas kini. Kerana anda memasangnya ke dalam prefix milik pengguna, kemas kini tidak memerlukan sudo:

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

Terdapat saluran keluaran: @latest adalah stabil, @preview adalah pratonton mingguan, @nightly adalah versi paling terkini — gunakan @latest untuk mana-mana sistem yang kritikal. Pada nvm, pakej global berada di bawah versi Node yang aktif, jadi selepas nvm use untuk menukar Node, anda mungkin perlu memasang semula CLI tersebut. Baca nota keluaran berbanding memantau setiap tampalan.

Mod kegagalan, dengan rentetan teks yang tepat

npm WARN EBADENGINE Unsupported engine ... required: { node: '>=20' }, kemudian CLI terhenti (crash) semasa runtime. Node terlalu lama — versi distro adalah 18.19.1, yang juga telah tamat tempoh sokongan (end-of-life). Pasang Node 20+ daripada NodeSource atau nvm, sahkan dengan node --version, dan jika anda mempunyai beberapa versi Node yang dipasang, pastikan which node merujuk kepada versi baharu dan bukan /usr/bin/node.

npm error code EACCES / permission denied, mkdir '/usr/lib/node_modules/...'. Pemasangan global ke dalam prefix milik root. Jangan gunakan sudo — tetapkan npm config set prefix ~/.npm-global, letakkan ~/.npm-global/bin pada PATH, dan pasang semula sebagai pengguna biasa anda. Jika sudo npm terdahulu meninggalkan fail cache milik root (Your cache folder contains root-owned files), jalankan sudo chown -R $(id -u):$(id -g) ~/.npm.

Failed to open browser, log masuk yang tergantung, atau redirect_uri=http://localhost:PORT yang tidak boleh dicapai. Aliran OAuth memerlukan pelayar web yang tiada pada pelayan, dan callback localhostnya merujuk kepada pelayan, bukan komputer riba anda. Gunakan laluan kunci API (GEMINI_API_KEY), atau tetapkan OAUTH_CALLBACK_PORT, alihkan melalui SSH dengan ssh -L, dan buka URL tersebut secara lokal.

Proses hilang apabila sambungan SSH terputus. Anda menjalankan gemini terus dari shell SSH, jadi ia adalah anak (child) kepada shell tersebut dan mati bersama pty semasa terputus sambungan. Tiada apa yang boleh dipulihkan. Mulakan setiap sesi dengan tmux new -A -s gemini dan jalankan CLI di dalamnya.

Pengesahan masih gagal walaupun kunci telah ditetapkan — CLI kembali ke pemilih pengesahan, atau permintaan mengembalikan API key not valid dengan HTTP 400. Kunci tersebut tidak berada dalam persekitaran (environment) yang dilihat oleh CLI. Sahkan dengan printenv GEMINI_API_KEY; jika ia kosong, ~/.gemini_env anda tidak pernah dimuatkan (sourced) — pastikan baris tersebut ada dalam ~/.bashrc, yang dibaca oleh shell interaktif (termasuk tmux) tetapi tidak oleh cron dan shell bukan interaktif yang lain. Ruang kosong atau tanda petik yang tersilap di dalam nilai kunci juga menyebabkan API key not valid.

429 / RESOURCE_EXHAUSTED / mesej had kadar (rate-limit). Anda telah mencapai kuota bagi tahap (tier) pengesahan yang digunakan. Tunggu sehingga tempoh tamat dijadualkan semula, perlahankan ejen, atau beralih ke kunci API berbayar. Ejen yang tersangkut dalam gelung cubaan semula (retry loop) akan terus terkena had ini — hentikan ejen tersebut dan semak apa yang sedang dilakukan.

FAQ

Bagaimanakah cara saya mengesahkan Gemini CLI pada pelayan headless?

Gunakan kunci API, bukan log masuk pelayar. Cipta kunci di Google AI Studio, masukkan ke dalam fail mode-600 yang disumber oleh shell anda (export GEMINI_API_KEY=...), dan CLI akan melangkau aliran pelayar OAuth sepenuhnya. Jika anda mahu pelan percuma akaun peribadi, tetapkan port loopback dengan OAUTH_CALLBACK_PORT=8085, alihkan (forward) ia kembali ke komputer riba anda dengan ssh -L 8085:localhost:8085 user@server, dan buka URL yang dicetak secara lokal — tetapi cara ini memerlukan anda berada di pelayar, jadi ia tidak sesuai untuk skrip.

Mengapa pemasangan npm global memerlukan sudo, dan bagaimanakah cara mengelaknya?

Kerana prefix global lalai npm ialah /usr/lib/node_modules, di mana pengguna anda tidak mempunyai hak akses tulis, maka npm install -g biasa akan gagal dengan EACCES. Penyelesaian yang salah ialah sudo npm -g, yang meninggalkan fail milik root yang akan merosakkan pemasangan kemudian hari. Penyelesaian yang betul adalah dengan menetapkan prefix ke direktori home anda (npm config set prefix ~/.npm-global) dan menambah bin ke dalam PATH, atau gunakan nvm, yang memasang pakej global di bawah direktori home anda secara automatik.

Bagaimanakah cara saya memastikan Gemini CLI terus berjalan selepas saya memutuskan sambungan?

Jalankannya di dalam tmux. Proses yang dimulakan daripada shell SSH anda akan terhenti apabila sambungan terputus kerana ia adalah anak (child) kepada shell tersebut; tmux menjalankan shell di bawah pelayan terpisah (detached server) yang kekal aktif walaupun sambungan terputus. Gunakan tmux new -A -s gemini, jalankan gemini di dalamnya, lepaskan (detach) dengan Ctrl-b d, dan sambung semula (reattach) kemudian dengan tmux attach -t gemini.

Adakah selamat untuk menjalankan Gemini CLI pada mesin produksi?

Hanya dengan berhati-hati, kerana ejen dengan akses shell boleh melakukan apa sahaja yang boleh dilakukan oleh pengguna yang menjalankannya. Jalankannya sebagai pengguna tanpa keistimewaan (unprivileged user) yang tiada sudo, jangan simpan kredensial produksi pada mesin tersebut, elakkan kelulusan automatik --yolo, dan gunakan --sandbox (Docker atau Podman) untuk mengasingkan panggilan alatan daripada hos. Akaun yang menjalankannya adalah lebih penting daripada mana-mana flag yang anda tetapkan.

Adakah saya perlu membuka mana-mana port firewall untuk Gemini CLI?

Tidak. Ia adalah klien yang membuat panggilan HTTPS keluar ke API Google, jadi ia memerlukan port 443 keluar tetapi tiada port masuk diperlukan. Jika anda menggunakan terowong OAuth, port callback yang ditetapkan (contohnya 8085) berada pada localhost dan dicapai melalui alihan SSH anda, bukan melalui port masuk yang terbuka. Kekalkan sekatan pada akses masuk.

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