SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor

如何在無頭 VPS 執行 Gemini CLI

在無瀏覽器的 VPS 執行 Google Gemini CLI:使用 Node 20+、免 sudo 全域安裝、API key 驗證與 tmux,避免 SSH 中斷導致長時間工作終止。

你要建置的內容

在你擁有的伺服器上執行常駐的 Gemini CLI,透過 SSH 存取,執行即使關閉筆電後仍會持續工作的長時間代理程式工作。安裝只需 3 個命令。真正需要處理的是所有以桌面環境為前提的部分:Google 的 CLI 會要求開啟瀏覽器登入,但你的伺服器沒有瀏覽器。因此,本指南大多說明無頭模式的流程、發行版不會提供的新版 Node、不需要 root 的全域 npm 安裝、將 API key 保存在 shell 歷史記錄之外的免瀏覽器驗證方式,以及 tmux,避免 SSH 連線中斷時一併終止執行中的工作。

Gemini CLI 是採用 Apache-2.0 授權的開放原始碼 Node 程式(@google/gemini-cli),可與 Google 的 Gemini 模型通訊,讀寫檔案、執行 shell 命令,並操作工作目錄中的工具。在 VPS 上,它是一個小型且隨時可用的代理程式,你可以讓它持續執行。因此,執行它的帳戶,以及儲存在伺服器上的憑證,比本指南中的任何單一設定更重要。

先決條件與必須注意的事項

  • 一台全新的 Ubuntu 24.04 KVM VPS,具備 root 或 sudo 權限。任何 KVM 方案皆可;CLI 本身很輕量,閒置時只需數百 MB RAM。
  • Node.js 20 或更新版本。這是唯一的硬性版本下限,而發行版套件低於此版本,請參閱下一節。Node 20 已於 April 30, 2026 終止支援,因此請安裝 24。
  • 對 Google API 開放輸出 HTTPS(port 443)。不需要任何輸入連接埠;這是用戶端而非伺服器,因此不必為此開放防火牆規則。
  • 一種不需要在伺服器上使用瀏覽器的驗證方式:使用 Google AI Studio 提供的付費 Gemini API key,或使用 Google sign-in。對於無頭主機,後者會要求你將驗證碼貼回終端機。API key 方式適合用於 script 與無人值守執行。
  • 只有在需要 --sandbox 隔離時才需要 Docker 或 Podman。這是選用項目,將在接近結尾處說明。

目前最容易造成問題的是帳戶,而不是瀏覽器。Google 於 May 19, 2026 宣布,自 June 18, 2026 起,Gemini CLI 將停止為 Google AI Pro 和 Ultra 訂閱者,以及免費使用者提供請求處理服務,並將這些使用者導向替代方案 Antigravity CLI(agy)。Gemini CLI 仍可搭配付費 Gemini API key、Gemini Enterprise Agent Platform API key,以及組織的 Gemini Code Assist Standard 或 Enterprise 授權使用。開始前,請先決定驗證方式。

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 會在不受支援的執行環境中運作。當它使用預期存在的 Node 20+ API 時,可能會發生異常或當機。Node 18 也已於 April 2025 終止支援,因此無論如何都不應繼續使用。請在安裝 CLI 之前 安裝目前的 LTS 版本。可選擇的做法有兩種:NodeSource(系統範圍的簽署 apt 套件庫)或 nvm(針對單一使用者的版本管理工具)。請擇一使用。

如果希望所有使用者都能在這台主機上使用 Node,請使用 NodeSource:

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 或更高版本,才能符合 CLI 的要求。但 Node 20 已於 April 30, 2026 終止支援,因此建議使用 v24.x,也就是目前的 active LTS。Node 26 預計於 October 28, 2026 成為 active LTS。請查看 NodeSource 頁面上的目前設定指令;URL 中的 setup_24.x 是新 LTS 發行後需要更新的版本欄位。

如果希望將 Node 保留在單一使用者的 home 目錄中,且完全不使用 sudo 修改它,請使用 nvm:

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

此 URL 中的 v0.40.1 是本文撰寫時的目前版本;執行前請查看 nvm 的 README,確認最新版本後替換 URL 中的版本。nvm 對此用途有一項實際優勢:它會將 Node 與全域套件安裝在 ~/.nvm 下,因此下一節所述的全域安裝權限問題不會發生。如果選擇 nvm,可略過 npm-prefix 步驟。

安裝 CLI,不使用 sudo npm -g

看似合理的指令是 sudo npm install -g @google/gemini-cli。不要這樣做。由 root 擁有的全域 prefix 會導致之後每次安裝都發生權限錯誤,並在 npm 快取中留下由 root 擁有的檔案,數個月後仍可能造成問題。對系統 Node 執行不使用 sudo 的 npm install -g,則會遇到另一個錯誤:

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,而是將 npm 的全域 prefix 指向家目錄,讓全域安裝內容寫入你擁有的路徑:

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 是刻意的:你將在兩個段落後於 tmux 中執行 CLI。tmux 會啟動非 login shell,讀取 ~/.bashrc 並略過 ~/.profile。因此,若將 PATH 行放在錯誤的檔案中,gemini 就會在你需要它的地方無法使用。gemini --version 能輸出版本號就是完整的測試結果。若改為取得 gemini: command not found,表示你的 PATH export 未生效,請參閱失敗情況。使用 nvm 時,完全略過 prefix 行:nvm 已經將全域套件安裝在你的家目錄下。

如果你先前曾執行 sudo npm,現在看到 Your cache folder contains root-owned files,請使用 sudo chown -R $(id -u):$(id -g) ~/.npm 修復一次。

無頭式驗證問題,以及如何排除

第一次以互動方式執行 gemini 時,系統會提供使用 Google 帳戶登入的選項。在桌面環境中,系統會開啟瀏覽器分頁。在無頭式 Linux VPS 上,CLI 會先檢查顯示環境;如果未設定 DISPLAY、WAYLAND_DISPLAY 或 MIR_SOCKET,就完全不會嘗試啟動瀏覽器。它會列出登入連結,並等待你貼回驗證碼:

Please visit the following URL to authorize the application:

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

Enter the authorization code:

這個流程可透過一般 SSH 使用,但每次都需要操作瀏覽器。此外,自 June 18, 2026 起,只有仍受 Gemini CLI 支援的 Google 帳戶才能使用此方式登入。

有兩種直接可行的方式。

第一種是使用 API key,這也是伺服器的建議預設方式。在 Google AI Studio(aistudio.google.com)中,於已啟用計費功能的專案建立金鑰,因為 Gemini CLI 已不再提供免費使用,然後將金鑰以環境變數提供給 CLI;它會讀取 GEMINI_API_KEY,並完全略過瀏覽器登入流程。接著處理「避免金鑰出現在歷史記錄及其他人可讀取的檔案中」的問題。請勿在提示字元中輸入 export GEMINI_API_KEY=AIza...,因為內容會以明文寫入 ~/.bash_history;也不要將它放在其他人可讀取的檔案中。請將它寫入 shell 啟動時會讀取的 mode-600 檔案:

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 會改用驗證方式選擇器,而不是使用該金鑰。若偏好這種配置方式,它也會讀取 ~/.gemini/ 中的 .env 檔案;規則相同,因此 chmod 600 ~/.gemini/.env。

第二種方式是直接使用 Google 登入。在無頭式主機上,這不需要 tunnel,也不需要開放連接埠。自 June 18, 2026 起,這主要適用於組織所持有的 Gemini Code Assist Standard 或 Enterprise 授權(也一併設定 GOOGLE_CLOUD_PROJECT);免費個人帳戶,以及 Google AI Pro 或 Ultra 訂閱,已不再受支援。透過一般 SSH 工作階段啟動 CLI,然後選擇 Sign in with Google:

gemini

將顯示的 URL 複製到筆記型電腦的瀏覽器中並核准。Google 會重新導向至 https://codeassist.google.com/authcode,該頁面會顯示授權碼;將它貼到 VPS 上的 Enter the authorization code: 提示字元,登入即完成。伺服器不會等待回呼,因此不需要固定連接埠,也不需要設定 ssh -L。只有當 CLI 偵測到顯示環境時,才會使用迴送流程,因此 OAUTH_CALLBACK_PORT 僅對該流程有影響。如果你使用 X11 forwarding(ssh -X)連線,系統會設定 DISPLAY,CLI 便會改用迴送流程,並將重新導向至伺服器上的 http://127.0.0.1:PORT/oauth2callback;執行 NO_BROWSER=true gemini 可強制使用貼上驗證碼的流程。這種方式可以運作,但需要你在瀏覽器前操作,因此不適合指令碼。對於需要持續執行的工作,請使用 API key。

如果使用 Vertex AI 或 Google Cloud 專案,而不是 AI Studio,請搭配 GOOGLE_GENAI_USE_VERTEXAI=true 設定 GOOGLE_API_KEY,或為 Code Assist 授權設定 GOOGLE_CLOUD_PROJECT;環境變數管理原則相同,也應使用 mode-600 檔案。

在 tmux 中執行,避免 SSH 連線中斷導致程序終止

直接從 SSH shell 啟動的 gemini 程序,是該 shell 的子程序。連線中斷、筆電闔上、Wi-Fi 中斷或閒置逾時時,sshd 會拆除虛擬終端機,shell 會收到 SIGHUP,接著也會中斷 CLI。已執行 10 分鐘、正在編輯檔案的工作會一併終止,重新連線後也沒有程序可供恢復。

tmux 會接管 shell,而不是由 sshd 接管 shell,因此能解決這個問題。這與在遠端 VPS 的 tmux 中執行 AI 程式碼代理採用相同模式,這裡的運作方式也完全相同:

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

如果名為 gemini 的工作階段已存在,tmux new -A -s gemini 會連接到該工作階段;如果不存在,則建立該工作階段。因此,每次登入後直接執行這個指令即可。工作階段內的 shell 隸屬於已分離的 tmux 伺服器,而不是 SSH 連線,因此連線中斷後 CLI 仍會繼續執行。重新連線並附加到工作階段後,即可回到相同的捲動內容。如果你在同一台主機上執行多個代理工作階段,應為每個工作階段使用一個 tmux 工作階段。這些工作階段在此無法互相通訊,不同於 Claude Code;在 Claude Code 中,同一台 VPS 上的一個工作階段可以將文字交給另一個工作階段。因此,請讓每個 Gemini 工作彼此獨立,或透過磁碟上的檔案協調。

對於非互動式的指令碼執行,Gemini CLI 提供無頭模式:gemini -p "summarise the failing tests in this repo" 會輸出回答並結束,而 --output-format json 會提供可供管線傳遞至其他程序的機器可讀輸出。在 tmux 工作階段中執行長時間批次工作,或從 cron 項目啟動工作時,搭配 API key 使用無頭模式正是適合的做法,但有一項注意事項:cron 工作不會載入任何登入檔案。因此,請在 crontab 這一行中提供專屬的 GEMINI_API_KEY,或讓指令載入 ~/.gemini_env;否則工作會因缺少認證資訊而失敗。

在同時執行正式環境的主機上進行沙箱隔離與權限管理

具備 shell 存取權的 agent 就等同具備 shell 權限。Gemini CLI 可以執行命令,預設會在每個具風險的命令執行前要求確認,但使用者可能會啟用 --yolo(自動核准所有工具呼叫)。如此一來,它就能以自身執行帳號的完整權限刪除檔案、推送至 git,或存取內部服務。在同時執行正式環境的主機上,這會造成實際的影響範圍,而不是假設性的風險。

以下列出 3 項控制措施,依效益由高至低排列:

  • 使用專用的非特權使用者執行。 不要使用 root,也不要讓該帳號加入 sudo。建立一個 agent 使用者,為其配置獨立的家目錄,並在該目錄中安裝 Node 與 CLI。即使誤解指示,影響也會限制在該帳號的範圍內。這是效益最高的單一決策。
  • 不要將正式環境憑證存放在該主機上。 不要存放正式環境的 ~/.aws/credentials,不要從正式環境複製 .env,也不要提供對任何重要資源具備寫入權限的資料庫密碼。改用 staging 憑證或唯讀憑證。
  • 使用內建沙箱。 安裝 Docker 或 Podman 後,gemini --sandbox(或 GEMINI_SANDBOX=docker)會在容器內執行 agent 的工具呼叫。該容器只掛載目前的專案目錄,不會掛載主機檔案系統的其他部分。這不能取代非特權使用者,但當同一台 VPS 正在執行正式工作時,能提供強效的第二層隔離。

如果你在其他自架工具旁執行 Gemini CLI,例如在同一台 VPS 上執行向 agent 提供工具的 MCP 伺服器,應將每項新增的功能視為 agent 可存取範圍的擴大,並將提供給它的 token 限制為單一工作所需的權限。

配額、費用與所選的驗證途徑

驗證途徑會決定計費方式;自 2026 年 6 月 18 日起,也會決定是否能使用服務。根據 Google 的公告,自該日起,Gemini CLI 不再為 Google AI Pro 與 Ultra 訂閱者,以及任何免費使用者提供服務。這包括個人帳戶的免費方案與未計費的 API keys。Gemini CLI 仍可透過按 token 計費的付費 Gemini API keys 與 Gemini Enterprise Agent Platform API keys 使用;擁有 Gemini Code Assist Standard 或 Enterprise 授權,或具備其他 Google Cloud 存取權的組織,則透過 Google Cloud 計費。每個方案仍有每分鐘與每日限制;超過限制後,請求會傳回速率限制錯誤,直到限制視窗重設。

有兩點需要注意。無人值守的 agent 若持續迴圈執行,可能會快速耗盡配額,因此在交由 cron 工作排程前,先觀察它執行幾次。若你在伺服器端使用模型的原因是隱私或不受計量的推論,而不是使用 Google 託管的模型,那就是另一種工具。使用 Ollama 在 VPS 上自行託管開放式 LLM 可將模型權重與提示保留在自己的主機上,但代價是必須執行遠小於 Gemini 的模型。

保持更新

Gemini CLI 經常發布新版本。由於您將它安裝到使用者擁有的 prefix 中,因此更新時不需要 sudo:

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

Gemini CLI 提供多個發行通道:@latest 是穩定版,@preview 是每週預覽版,@nightly 是最新開發版。對於任何相依的環境,請固定使用 @latest。使用 nvm 時,全域套件會安裝在目前啟用的 Node 版本下。因此,在執行 nvm use 切換 Node 版本後,可能需要重新安裝 CLI。請閱讀發行說明,不要追逐每個修補程式版本。

失敗模式與精確字串

npm WARN EBADENGINE Unsupported engine ... required: { node: '>=20' },接著 CLI 在執行時當機。 Node 版本過舊;該發行版提供的是 18.19.1,而這個版本也已超過生命週期。請從 NodeSource 或 nvm 安裝目前的 LTS 版本,確認結果:node --version。如果安裝了多個 Node,請確認 which node 指向新版,而不是 /usr/bin/node。

npm error code EACCES / permission denied, mkdir '/usr/lib/node_modules/...'。 這表示全域安裝目標位於 root 擁有的 prefix。不要使用 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://127.0.0.1:PORT。 CLI 找到了顯示變數(通常來自 ssh -X),因此採用 loopback 流程,而回呼會連回伺服器。請執行 NO_BROWSER=true gemini 以使用貼上程式碼的流程,或改用 API key 流程(GEMINI_API_KEY)。在一般 SSH 工作階段中,應該會看到 Enter the authorization code:;請在筆記型電腦的瀏覽器中核准該 URL,然後貼上 Google 顯示的程式碼。

SSH 連線中斷時,程序也消失了。 你直接從 SSH shell 執行 gemini,因此它是該 shell 的子程序,斷線時也隨著 pty 結束。沒有可復原的程序。每次工作階段都先啟動 tmux new -A -s gemini,再在其中執行 CLI。

已設定 key,但驗證仍然失敗;CLI 返回驗證選擇器,或請求以 HTTP 400 返回 API key not valid。 CLI 看不到所在環境中的 key。請以 printenv GEMINI_API_KEY 確認;如果結果為空,表示你的 ~/.gemini_env 從未被載入。請確認該行位於 ~/.bashrc;互動式 shell(包括 tmux)會讀取它,但 cron 及其他非互動式 shell 不會。key 值中多出的空格或引號也會產生 API key not valid。

429 / RESOURCE_EXHAUSTED / 速率限制訊息。 你已達到驗證所使用層級的配額。請等待配額視窗重設、降低 agent 的執行速度,或改用計費 API key。陷入重試迴圈的 agent 會持續觸發此問題;請停止它並檢查其行為。

FAQ

如何在無頭伺服器上驗證 Gemini CLI?

請使用付費 API key,不要使用瀏覽器登入。請在 Google AI Studio 的計費專案中建立 key,將其存放在 shell 會載入的 mode-600 檔案中(export GEMINI_API_KEY=...),CLI 就會完全略過 OAuth 瀏覽器流程。若改用 Google 登入,例如使用 Code Assist Standard 或 Enterprise 授權,無頭伺服器上的 CLI 會顯示 URL;請在筆記型電腦上開啟該 URL、完成核准,再將 Google 顯示的 code 貼回 Enter the authorization code: 提示字元。無須固定連接埠,也不需要 tunnel,但必須有人操作瀏覽器,因此不適合用於 script。自 June 18, 2026 起,Gemini CLI 已不再提供給免費個人帳戶使用。

為什麼 npm 的全域安裝需要 sudo?如何避免?

因為 npm 預設的全域 prefix 是 /usr/lib/node_modules,目前使用者沒有寫入權限,因此直接執行 npm install -g 會因 EACCES 而失敗。錯誤的作法是使用 sudo npm -g,這會留下由 root 擁有的檔案,導致後續安裝失敗。正確作法是將 prefix 指向家目錄(npm config set prefix ~/.npm-global),並將其 bin 加入 PATH;或者使用 nvm,讓全域套件自動安裝在家目錄下。

如何在中斷連線後讓 Gemini CLI 繼續執行?

請在 tmux 中執行。從 SSH shell 啟動的程序是該 shell 的子程序,連線中斷時會隨之結束;tmux 會在 detached server 下執行 shell,因此即使連線中斷仍能存活。請使用 tmux new -A -s gemini,在其中執行 gemini,使用 Ctrl-b d detach,之後再使用 tmux attach -t gemini 重新連線。

在 production box 上執行 Gemini CLI 是否安全?

只有在謹慎設定的情況下才安全,因為具備 shell 存取權限的 agent 可以執行其使用者帳戶能執行的任何操作。請以專用的非特權使用者執行,不要授予 sudo 權限,勿將 production credentials 存放在該機器上,避免使用 --yolo 自動核准,並使用 --sandbox(Docker 或 Podman)將 tool calls 與主機隔離。執行該程序的帳戶,比你設定的任何單一 flag 都更加重要。

執行 Gemini CLI 需要開放任何防火牆連接埠嗎?

不需要。它是向 Google API 發出對外 HTTPS 請求的 client,因此只需要對外連線的 443 埠,不需要任何入站連接埠。無頭伺服器上的 Google 登入也不需要連接埠:你只需將 code 貼回 terminal,而不是在伺服器上接收 callback。請維持入站連線的限制。

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