SSD Nodes Learn Hosting plans →
ガイド Matt Connor著者 Matt Connor

ヘッドレスVPSでGemini CLIを動かす方法

Ubuntu 24.04のヘッドレスVPSでGemini CLIを実行する手順です。Node.js 20以降、sudo不要のglobal npm install、API key認証、SSH切断に強いtmuxを使います。

構築するもの

自分で管理するサーバー上で常時稼働し、SSH 経由で接続できる Gemini CLI です。ノート PC を閉じた後も、長時間のエージェントタスクを実行し続けます。インストールは3つのコマンドで完了します。手間がかかるのは、デスクトップ環境を前提とする部分です。Google の CLI はログインのためにブラウザを開こうとしますが、サーバーにはブラウザがありません。そのため、このガイドの大部分では、ヘッドレス環境での手順、ディストリビューションでは提供されない新しい Node、root 権限を必要としないグローバル npm インストール、シェル履歴に残さない API key を使ったブラウザレス認証、そして SSH セッションが切断されても実行中のタスクを終了させない tmux を扱います。

Gemini CLI はオープンソース(Apache-2.0)の Node プログラム(@google/gemini-cli)です。Google の Gemini モデルと通信し、作業ディレクトリ内のファイルの読み書き、shell コマンドの実行、ツールの操作を行えます。VPS 上では、常時利用でき、実行を継続させておける小規模なエージェントとして機能します。そのため、ここで扱う個々の設定以上に、実行するアカウントとサーバー上に保存される認証情報が重要です。

前提条件と注意点

  • root または sudo を使用できる、Ubuntu 24.04 の新規 KVM VPS。どの KVM プランでも動作します。CLI 自体は軽量で、停止中は数百 MB の RAM があれば足ります。
  • Node.js 20 以降。これが唯一の厳格なバージョン要件です。ディストリビューションのパッケージは要件を満たさないため、次のセクションを参照してください。Node 20 自体は 2026 年 4 月 30 日にサポート終了となったため、24 をインストールしてください。
  • Google の API への送信 HTTPS(ポート 443)。受信ポートは不要です。これはサーバーではなくクライアントなので、ファイアウォールに受信許可を追加する必要はありません。
  • サーバー上でブラウザーを必要としない認証方法。Google AI Studio の有料 Gemini API key、または Google サインインを使用できます。ヘッドレス環境では、表示されたコードをターミナルに貼り付けます。API key を使う方法は、スクリプトや無人実行に適しています。
  • Docker または Podman。--sandbox の分離を使用する場合だけ必要です。任意の設定で、後半で説明します。

現在、最も見落とされやすいのはブラウザーではなくアカウントです。Google は 2026 年 5 月 19 日、2026 年 6 月 18 日以降、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 は、独自のリポジトリで npm 9.2.0 と組み合わせた Node 18.19.1 を提供しています。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 は 2025 年 4 月にサポート終了を迎えているため、いずれにしても選択肢にはなりません。CLI をインストールする 前に、現行の LTS をインストールしてください。方法は、NodeSource(システム全体で使う署名付き apt リポジトリ)または nvm(ユーザーごとのバージョンマネージャー)の2つです。どちらか1つを選択してください。

すべてのユーザーがサーバー上で 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

CLI の要件を満たすには、node --version が v20.x 以上を出力する必要があります。ただし、Node 20 は 2026 年 4 月 30 日にサポート終了を迎えるため、現行のアクティブ LTS である v24.x を使用してください。Node 26 は 2026 年 10 月 28 日にアクティブ LTS になる予定です。現在のセットアップスクリプトは NodeSource のページで確認してください。URL 内の setup_24.x が、新しい LTS がリリースされたときに更新する箇所です。

Node を1ユーザーのホームディレクトリ内だけで管理し、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 cache に 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 を使わないのには理由があります。2 セクション後に CLI を実行する tmux は、ログインシェルではないシェルを起動します。このシェルは ~/.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 を 1 回実行して修正します。

ヘッドレス環境での認証問題と、その解決方法

初回は gemini を対話的に実行すると、Google アカウントでのログインを求められます。デスクトップではブラウザーのタブが開きます。ヘッドレスの Linux VPS では、CLI が最初にディスプレイの有無を確認します。DISPLAY、WAYLAND_DISPLAY、MIR_SOCKET のいずれも設定されていない場合、ブラウザーの起動は試みません。代わりにサインイン用 URL を表示し、コードの貼り付けを待ちます。

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 アカウントでなければログインできません。

解決方法は、実質的に 2 つあります。

1 つ目は API key です。サーバーでは、これをデフォルトにするのが適切です。Google AI Studio (aistudio.google.com) で、課金を有効にした project に対して key を作成します。Gemini CLI は無料利用を提供しなくなったため、課金の有効化が必要です。作成した key は環境変数として 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 で key が環境変数に渡されたことを確認します。何も表示されない場合、CLI は key を使わず、認証方法の選択に戻ります。別の配置を使いたい場合、.env ファイルを ~/.gemini/ に置いても読み取ります。chmod 600 ~/.gemini/.env についても同じルールを適用してください。

2 つ目は、Google サインインそのものです。ヘッドレスのサーバーでは、トンネルも公開ポートも必要ありません。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: プロンプトに貼り付けます。これでログインが完了します。サーバー側では callback を待ち受けないため、固定するポートはありません。ssh -L を設定する必要もありません。OAUTH_CALLBACK_PORT が必要になるのは、CLI がディスプレイを検出したときに使う loopback フローだけです。X11 forwarding (ssh -X) で接続すると DISPLAY が設定され、CLI は代わりにこの loopback フローを使います。この場合、サーバー上の http://127.0.0.1:PORT/oauth2callback にリダイレクトされます。NO_BROWSER=true gemini を実行すると、コードを貼り付けるフローを強制できます。この方法は動作しますが、ブラウザーを操作する必要があるため、スクリプトには適していません。常駐させる処理では API key を使ってください。

AI Studio ではなく Vertex AI または Google Cloud project を使う場合は、GOOGLE_API_KEY と GOOGLE_GENAI_USE_VERTEXAI=true を設定します。Code Assist ライセンスの場合は GOOGLE_CLOUD_PROJECT を設定します。環境変数の扱いと mode-600 ファイルの使用については、同じ規則に従ってください。

tmux 内で実行し、切断された SSH セッションでプロセスを終了させない

SSH シェルから直接起動した gemini プロセスは、そのシェルの子プロセスです。接続の切断、ノート PC の終了、Wi-Fi の切断、アイドルタイムアウトなどが発生すると、sshd が擬似端末を破棄し、シェルが SIGHUP を受け取り、続いて CLI にもハングアップを送信します。ファイル編集を開始してから 10 分経過したタスクも同時に終了し、再接続しても復旧できるプロセスは残りません。

tmux は、シェルを sshd の子プロセスにする代わりに、自身がシェルを所有することでこの問題を解決します。これは リモート VPS 上で AI コーディングエージェントを tmux 内で実行する場合と同じ構成で、ここでも同じように機能します。

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 は gemini という名前のセッションが存在すれば接続し、存在しなければ作成します。そのため、ログインするたびに最初に実行するコマンドとして使えます。内部のシェルは SSH セッションではなく、デタッチされた tmux サーバーに属します。そのため接続が切れても CLI は動作し続けます。再接続してアタッチすれば、同じスクロールバックに戻れます。1 台のサーバーで複数のエージェントセッションを実行する場合は、tmux セッションを 1 つずつ割り当てます。この環境では、それらが互いに通信することはありません。これは Claude Code とは異なり、Claude Code では 同じ VPS 上の 1 つのセッションから別のセッションへテキストを渡せます。各 Gemini ジョブを独立して実行するか、ディスク上のファイルを介して連携してください。

非対話的なスクリプト実行では、Gemini CLI にヘッドレスモードがあります。gemini -p "summarise the failing tests in this repo" は回答を出力して終了し、--output-format json は別の処理へパイプできる機械可読形式の出力を生成します。API key を使用したヘッドレスモードは、長時間のバッチジョブを実行する tmux セッション内や、cron エントリから起動する場合に適しています。ただし、cron ジョブはログイン時のファイルを読み込まないため、crontab の行に独自の GEMINI_API_KEY を指定するか、コマンドで ~/.gemini_env を読み込ませてください。指定しないと、認証情報が見つからず実行に失敗します。

本番環境も稼働しているサーバーでのサンドボックス化と権限管理

shell にアクセスできるエージェントは、shell そのものです。Gemini CLI はコマンドを実行できます。デフォルトでは、リスクのあるコマンドを実行する前に確認を求めます。しかし、--yolo(すべてのツール呼び出しを自動承認)を使いたくなることがあります。その場合、実行ユーザーの権限を使って、ファイルの削除、git への push、内部サービスへのアクセスまで実行できます。本番環境も稼働しているサーバーでは、これは仮想的な問題ではなく、実際の被害範囲につながります。

効果の大きい順に、次の 3 つの対策を行います。

  • 専用の非特権ユーザーで実行する。 root ではなく、sudo のメンバーでもないユーザーを使います。専用のホームディレクトリを持つ agent ユーザーを作成し、そのユーザー環境に Node と CLI をインストールします。指示を誤って解釈しても、被害をそのアカウント内に限定できます。これは最も効果の高い判断です。
  • 本番環境の認証情報をサーバーに置かない。 本番用の ~/.aws/credentials、本番環境からコピーした .env、重要なデータに書き込み可能なデータベースパスワードは置きません。staging 用または読み取り専用の認証情報を渡します。
  • 組み込みのサンドボックスを使う。 Docker または Podman がインストールされている場合、gemini --sandbox(または GEMINI_SANDBOX=docker)を使うと、エージェントのツール呼び出しをコンテナ内で実行できます。コンテナには現在のプロジェクトディレクトリだけをマウントし、ホストファイルシステムの他の部分はマウントしません。これは非特権ユーザーの代わりにはなりません。しかし、同じ VPS で実際のサービスを運用している場合に、強力な第 2 層の対策になります。

Gemini CLI を他の self-hosted ツールと同じ環境で実行する場合、たとえば 同じ VPS 上でエージェントにツールを公開する MCP server を使う場合は、追加する機能ごとにエージェントが到達できる範囲が広がると考えてください。渡すトークンの権限は、1 つの作業に必要な範囲だけに限定します。

割り当て量、料金、選択した認証経路

認証経路によって請求方法が決まり、2026年6月18日以降は、そもそもサービスを利用できるかどうかも決まります。Googleの発表によると、この日以降、Gemini CLIはGoogle AI ProおよびUltraの加入者と、無料で利用しているユーザーへのリクエスト処理を停止しました。対象には、個人アカウントの無料枠と、請求先が設定されていないAPI keysが含まれます。引き続き利用できるのは、トークン単位で課金される有料のGemini API keysおよびGemini Enterprise Agent Platform API keysです。また、Gemini Code Assist StandardまたはEnterpriseのライセンス、あるいはその他のGoogle Cloudアクセス権を持つ組織は、Google Cloud経由で課金されます。どのティアにも、分単位および日単位の上限があります。上限を超えると、ウィンドウがリセットされるまでリクエストはレート制限エラーを返します。

実務上の注意点が2つあります。ループ内でエージェントを無人実行すると、割り当て量をすぐに消費することがあります。そのため、cron jobに任せる前に、最初の数回は動作を監視してください。また、サーバー側モデルを使う理由が、Googleのホスト型モデルではなく、プライバシーや従量制限のない推論である場合は、別のツールが適しています。OllamaでVPS上にオープンLLMをセルフホストすると、モデルの重みとプロンプトを自分のサーバー内に保持できます。ただし、Geminiよりもはるかに小さいモデルを運用することになります。

最新状態に保つ

Gemini CLI は頻繁にリリースされます。ユーザー所有の prefix にインストールしたため、更新時に sudo は必要ありません。

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

リリースチャネルには、安定版の @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 20 は CLI の最低要件を満たしますが、2026年4月以降はそれ自体もサポート終了です。node --versionで確認し、Node を複数インストールしている場合は、which nodeが /usr/bin/nodeではなく新しい 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、または到達できない http://127.0.0.1:PORTを指す redirect_uri。 CLI は表示変数を検出し(多くの場合 ssh -Xから)、コールバックがサーバーに到達するループバック方式を選択しました。NO_BROWSER=true geminiを実行してコード貼り付け方式に切り替えるか、API キー方式(GEMINI_API_KEY)を使用してください。通常の SSH セッションでは、代わりに Enter the authorization code:が表示されるはずです。ノート PC のブラウザーで URL を承認し、Google が表示するコードを貼り付けます。

SSH が切断されたときにプロセスが消えた。 SSH シェルから geminiを直接実行したため、そのシェルの子プロセスとなり、切断時に pty とともに終了しました。復旧するものはありません。すべてのセッションを tmux new -A -s geminiで開始し、その中で CLI を実行してください。

キーを設定しても認証に失敗する、CLI が認証選択画面に戻る、またはリクエストが API key not validを HTTP 400で返す。 CLI が参照する環境にキーがありません。printenv GEMINI_API_KEYで確認してください。空の場合、~/.gemini_envが読み込まれていません。~/.bashrcにその行があることを確認してください。interactive shell(tmux を含む)はこのファイルを読み込みますが、cronなどの非 interactive shell は読み込みません。キーの値に余分な空白や引用符がある場合も、API key not validが発生します。

429 / RESOURCE_EXHAUSTED / レート制限メッセージ。 認証に使用している tier の quota に達しました。ウィンドウがリセットされるまで待つか、agent の速度を下げるか、有料の API キーに切り替えてください。agent が再試行ループに陥るとこの状態が続くため、停止して動作を確認します。

FAQ

Gemini CLI をヘッドレスサーバーで認証するにはどうすればよいですか?

ブラウザログインではなく、有料の API key を使用します。請求対象の project で Google AI Studio に key を作成し、shell が読み込む mode-600 のファイル(export GEMINI_API_KEY=...)に保存します。これで CLI は OAuth のブラウザフローを完全にスキップします。Google でサインインする場合、たとえば Code Assist Standard または Enterprise licence を使用する場合は、ヘッドレス環境の CLI が URL を表示します。その URL を laptop で開いて承認し、Google が表示する code を Enter the authorization code: prompt に貼り付けます。固定する port も tunnel も必要ありません。ただしブラウザ操作が必要なため、script には適していません。Free personal account は 2026 年 6 月 18 日以降、Gemini CLI で提供されていません。

npm の global install で sudo を求められるのはなぜですか。また、どうすれば回避できますか?

npm のデフォルトの global prefix が /usr/lib/node_modules であり、ユーザーには書き込み権限がないためです。そのため、通常の npm install -g は EACCES で失敗します。誤った対処は sudo npm -g です。root 所有のファイルが残り、後続の install が失敗する原因になります。正しい対処は、prefix をホームディレクトリ(npm config set prefix ~/.npm-global)に設定し、その bin を PATH に追加することです。または nvm を使用します。nvm なら global package が自動的にホームディレクトリ配下へインストールされます。

切断後も Gemini CLI を実行し続けるにはどうすればよいですか?

tmux の内部で実行します。SSH shell から起動したプロセスは、その shell の子プロセスであるため、接続が切れると終了します。tmux は shell を detach された server の配下で実行するため、切断後も存続します。tmux new -A -s gemini を使用して、内部で gemini を実行します。Ctrl-b d で detach し、後で tmux attach -t gemini で再接続します。

本番環境のサーバーで Gemini CLI を実行しても安全ですか?

慎重に運用する場合に限り安全です。shell access を持つ agent は、実行ユーザーに許可された操作をすべて実行できるためです。専用の非特権ユーザーで実行し、sudo を付与しないでください。本番環境の credential をサーバーに置かず、--yolo の自動承認を避け、--sandbox(Docker または Podman)を使用して tool call を host から分離します。設定する個々の flag よりも、実行ユーザーの account の権限が重要です。

Gemini CLI のために firewall port を開く必要はありますか?

いいえ。Gemini CLI は Google の API に対して outbound HTTPS call を行う client です。そのため outbound port 443 は必要ですが、inbound port は必要ありません。ヘッドレス環境での Google サインインにも port は不要です。server で callback を受信する代わりに、code を terminal に貼り付けます。inbound access は閉じたままにしてください。

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