SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-30

如何在無頭 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 或更新版本。這是唯一硬性的版本下限,而發行版套件版本低於此要求,請參閱下一節。
  • 可對 Google API 建立對外 HTTPS 連線(port 443)。不需要任何對外開放的連接埠;這是用戶端而非伺服器,因此不必為它開放防火牆規則。
  • 不需要在伺服器上使用瀏覽器的驗證方式:可以使用 Google AI Studio 的 Gemini API key,或建立 SSH tunnel,連回自己電腦上的瀏覽器。API key 方式適合擴充至 script 與無人值守執行。
  • 只有在需要 --sandbox 隔離時才需要 Docker 或 Podman。這是選用項目,本文末尾附近會說明。

最容易造成問題的一點是:方便的 gemini 首次執行登入流程是為桌面環境設計的。它會嘗試開啟瀏覽器;在無頭主機上,可能直接失敗,或提供無法使用的連結。開始前先決定驗證方式。

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 或更高版本;v24.x 是目前的 active LTS。請查看 NodeSource 頁面上的目前設定指令碼;URL 中的 setup_24.x 是新版 LTS 發布時需要更新的版本號。

如果希望將 Node 保留在單一使用者的家目錄中,且完全不使用 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 帳戶登入的選項。在桌面環境中,程式會開啟瀏覽器分頁。在 headless VPS 上沒有瀏覽器,因此流程可能會輸出要求你開啟的 localhost URL,或直接失敗並顯示如下訊息:

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

問題在於 redirect_uri=http://localhost:PORT。即使你在筆記型電腦上開啟該 URL 並完成核准,Google 仍會重新導向至 http://localhost:PORT。這是伺服器上的 localhost,筆記型電腦無法連線到該埠。登入流程不會完成。

有兩種正確的處理方式。

第一種方式是使用 API key,這也是伺服器的預設建議。請在 Google AI Studio(aistudio.google.com)建立 key,並透過環境變數傳給 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 確認 key 已載入環境;若沒有輸出內容,CLI 會退回瀏覽器流程並失敗。如果你偏好該配置方式,程式也會讀取 .env 中的 ~/.gemini/,規則相同,因此 chmod 600 ~/.gemini/.env

第二種方式會保留個人 Google 帳戶登入方式及其免費方案,方法是將 OAuth 回呼通道轉送回筆記型電腦。問題是 CLI 的 loopback server 每次執行都會繫結至隨機埠;除非先使用 OAUTH_CALLBACK_PORT 環境變數固定埠號,否則沒有固定的目標可供轉送。固定後,請精確轉送該埠:

# 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 無法開啟瀏覽器,因此會輸出驗證 URL。請在筆記型電腦的瀏覽器中開啟該 URL 並完成核准。Google 重新導向至 http://localhost:8085/... 時,SSH forward 會將請求轉送至 VPS 上的 loopback server,登入流程即可完成。如果不固定埠號,每次執行都會使用新的隨機埠,預先設定的任何 ssh -L 都無法接收該請求。這種方式可行,但需要你在瀏覽器前操作,因此不適合指令碼。對於需要持續執行的工作,請使用 API key。

如果改用 Vertex AI 或 Google Cloud project,而不是 AI Studio,請搭配 GOOGLE_GENAI_USE_VERTEXAI=true 設定 GOOGLE_API_KEY;若使用 Code Assist licence,則設定 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 coding agent採用相同模式,在此也完全相同:

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 server,而不是 SSH 工作階段,因此即使連線中斷,CLI 仍會繼續執行。重新連線並附加至工作階段後,就能回到相同的捲動歷史記錄。如果要在同一台主機上執行多個 agent 工作階段,請為每個工作階段使用一個 tmux 工作階段。這些工作階段在此無法彼此通訊,不同於 Claude Code;在 Claude Code 中,同一台 VPS 上的一個工作階段可以將文字交給另一個工作階段。因此,請讓每個 Gemini 工作彼此獨立,或透過磁碟上的檔案進行協調。

對於非互動式的指令碼執行,Gemini CLI 提供 headless mode:gemini -p "summarise the failing tests in this repo" 會輸出答案後結束,--output-format json 則會提供可供管線轉送的機器可讀輸出。在 tmux 工作階段中執行長時間批次工作,或從 cron 項目啟動工作時,搭配 API key 使用 headless mode 正是適合的方式。但有一項限制:cron job 不會載入任何登入檔案。因此,請在 crontab 行中指定專用的 GEMINI_API_KEY(或讓命令載入 ~/.gemini_env),否則 CLI 會退回瀏覽器流程並執行失敗。

同時執行正式環境的主機:沙箱與權限

具備 shell 存取權的代理程式,就等同於具備 shell 存取權。Gemini CLI 可以執行命令,預設會在每次執行具風險的命令前詢問確認;但使用者常會改用 --yolo(自動核准每次工具呼叫)。如此一來,代理程式就能以其執行帳號的完整權限刪除檔案、推送至 git,或存取內部服務。在同時執行正式環境服務的主機上,這會造成實際的影響範圍,並非假設性風險。

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

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

如果你在其他自架工具旁執行 Gemini CLI,例如在同一台 VPS 上使用向代理程式公開工具的 MCP server,請將每項新增能力視為代理程式可存取的額外攻擊面,並將提供給它的權杖限制在單一工作所需的範圍內。

配額、費用,以及你選擇的驗證路徑

驗證路徑會決定計費方式。個人 Google 帳戶(OAuth 路徑)使用免費的 Gemini Code Assist 方案,具有實際的每分鐘與每日限制;超過限制後,請求會回傳速率限制錯誤,直到限制視窗重設。AI Studio 的 API key 可能使用免費方案,也可能依專案計費;付費的 key 會提高限制,並依 token 計費。Vertex 與 Cloud 專案驗證則會透過 Google Cloud 計費。

請注意兩點。未受管理、持續迴圈執行的 agent 可能很快耗盡配額,因此在交由 cron job 執行前,前幾次應先加以監控。如果你選擇伺服器端模型的原因是隱私或不受用量限制的推論,而不是使用 Google 託管的模型,那就是另一種工具;在 VPS 上以 Ollama 自行託管開放式 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 安裝 Node 20+,使用 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://localhost:PORT OAuth 流程需要瀏覽器,但伺服器沒有瀏覽器;localhost 回呼也會指向伺服器,而不是你的筆電。請使用 API key 路徑(GEMINI_API_KEY),或固定使用 OAUTH_CALLBACK_PORT,再透過 SSH 使用 ssh -L 轉送,並在本機開啟 URL。

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

已設定 key,但驗證仍失敗,CLI 返回驗證選擇器,或請求回傳 API key not valid 與 HTTP 400 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 建立金鑰,將金鑰放入 shell 會載入的 mode-600 檔案(export GEMINI_API_KEY=...)中,CLI 就會完全略過 OAuth 瀏覽器流程。如果您特別需要個人帳戶的免費方案,請使用 OAUTH_CALLBACK_PORT=8085 固定 loopback 連接埠,再使用 ssh -L 8085:localhost:8085 user@server 將該連接埠轉送回您的筆記型電腦,並在本機開啟輸出的 URL。但這需要您在瀏覽器前操作,因此不適合用於腳本。

為什麼 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,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 主機上執行 Gemini CLI 是否安全?

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

使用 Gemini CLI 是否需要開啟防火牆連接埠?

不需要。Gemini CLI 是向 Google API 發出對外 HTTPS 請求的用戶端,因此需要對外連接埠 443,但不需要任何對內連接埠。如果使用 OAuth tunnel,固定的 callback 連接埠(例如 8085)會位於 localhost,並透過 SSH forward 存取,而不是開放的對內連接埠。請維持對內連線的嚴格限制。

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