Ivaを小規模VPSでセルフホストする方法
Telegram AIアシスタントIva v0.3.13を小規模VPSで運用します。開放ポートやドメインは不要で、systemd user serviceとObsidian対応のMarkdownメモリをバックアップできます。
構築するもの
Iva はセルフホスト型の Telegram AI アシスタントです。外部からの受信ポートを開放する必要も、接続先としてドメインを指定する必要もない、数少ない構成の 1 つです。サーバー上で外部公開用に待ち受けるものがないため、証明書も必要ありません。サービスは Telegram へ外向きに接続し、その接続を維持しながら、応答からメッセージを読み取ります。その他の仕組みは、すべてこの 1 本の外向き接続を基盤としています。
Iva は MIT ライセンスで提供され、Node で記述されています。メモリには通常の markdown ファイルを保存します。これらのファイルは Obsidian で直接開けるため、アプリケーションが保持するユーザー情報を、アプリケーションなしでも読み取れます。このガイドでは、2026 年 8 月 6 日に公開された release v0.3.13 を使用します。
ほとんどのセルフホスト型ソフトウェアでは、DNS (domain name system) レコードと Certbot で発行する Let's Encrypt 証明書から構築を始めます。Iva ではこの層を完全に省略できます。そのため、SSH のみを許可するファイアウォールの背後にある小規模な VPS だけで、完全なデプロイメントを構成できます。
Iva に開放ポートが不要な理由
iva-telegram-poll.service はロングポーリングブリッジです。Telegram の getUpdates API を呼び出して応答を待つため、すべての接続はサーバーから開始されます。Telegram から接続してくることはありません。そのため、リバースプロキシの設定も証明書の更新も必要ありません。
エージェント自体は 127.0.0.1 ポート 8723 のみで待ち受けます。プロジェクトのドキュメントにも明記されているとおり、ポート 8723 は公開しないでください。前段にリバースプロキシを置く場合も、ベアラートークンの要件を維持する必要があります。インストール後にバインドアドレスを確認してください。
sudo ss -tlnp | grep 8723アドレスは 127.0.0.1:8723 になっている必要があります。0.0.0.0:8723 のようなワイルドカードアドレスでは、エージェントの HTTP ルートがインターネットから到達可能になります。ボットにプライベートな情報を送る前に修正してください。
そのため、ファイアウォールは閉じたままにします。有効化する前に SSH を許可してください。SSH ルールのない ufw enable を実行すると、入力中のセッションが切断されます。
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw status1 行のインストーラーが実際に行う処理
プロジェクトのトップページには、GitHub からスクリプトを取得して bash に渡す 1 つのコマンドが示されています。1 つのプログラムをインストールするだけではないため、先にスクリプトを読んでください。
curl -fsSL https://raw.githubusercontent.com/smixs/iva/main/install.sh -o iva-install.sh
less iva-install.sh- 検出したパッケージマネージャーを使用して、システムパッケージ
git、gh、python3、ffmpeg、pandoc、poppler-utilsをインストールします。 - RAM が 1.5 GB 未満で、swap がない場合は、
/swapfileに 2 GB の swapfile を作成します。swap がないとビルドが強制終了されるためです。 - nvm をインストールし、続いて Iva が動作する最小バージョンである Node 24 をインストールします。
- Python パッケージマネージャーである
uvを~/.local/binにインストールします。 - リポジトリを
~/ivaに clone し、npm ciを実行します。 - グローバル npm パッケージ
agent-browserと@googleworkspace/cliをインストールします。agent-browserはその後 Chromium をダウンロードします。 - セットアップウィザードを実行し、プロジェクトをビルドして、vault を作成します。
ivaコマンドを~/.local/binに書き込み、systemd の user unit をインストールします。
1 行のコマンドで、これだけ多くのソフトウェアを導入します。README が、root ではなく通常のユーザーでインストールするよう指示している理由も分かります。後で agent の shell ツールが、インストーラーを実行したユーザーの権限で動作するためです。スクリプトが sudo を呼び出すのは、パッケージのインストールと swapfile の作成だけです。これらの処理では、すでに root であればコマンドを直接実行する 1 つのヘルパーを使用します。
インストール前に専用ユーザーを作成する
Iva 専用のアカウントを作成します。エージェントはコンテナやサンドボックスを使わず、Node の child_process を介してホスト上でシェルコマンドを実行します。そのため、エージェントを実行するアカウントがセキュリティ境界になります。
sudo adduser --disabled-password --gecos "" iva
sudo usermod -aG sudo iva
sudo install -d -m 700 -o iva -g iva /home/iva/.ssh
sudo cp ~/.ssh/authorized_keys /home/iva/.ssh/authorized_keys
sudo chown iva:iva /home/iva/.ssh/authorized_keys
sudo chmod 600 /home/iva/.ssh/authorized_keys
sudo loginctl enable-linger ivaIva は systemd の user unit として実行されるため、enable-linger が重要です。linger を有効にしない場合、最後のセッションが終了した時点で systemd がそのユーザーのサービスを停止します。そのため、SSH を閉じるとアシスタントも終了します。同じルールは、systemd の下で自分で作成する サービスとタイマー にも適用されます。
このアカウントに必要なのは、インストーラーがパッケージを追加するときだけ sudo です。インストールが完了したら、sudo を削除します。
sudo deluser iva sudoSSH で、そのユーザーとして直接ログインします。sudo -iu iva で入ったシェルには DBUS_SESSION_BUS_ADDRESS も XDG_RUNTIME_DIR も設定されていません。そのため、すべての systemctl --user コマンドが Failed to connect to bus で失敗します。この境界を設けることは、最小権限のユーザーでサービスを実行することと同じ考え方です。
bash にパイプせず、固定したリリースをインストールする
このインストーラーには便利な特性があります。何かを clone する前に、スクリプトが置かれているディレクトリに "eve" を含む package.json がすでにあるか確認します。存在する場合は、その checkout をビルドして clone を省略します。そのため、バージョンを自分で選択できます。
git clone --branch v0.3.13 https://github.com/smixs/iva.git ~/iva
cd ~/iva
git log -1 --oneline
bash install.shこれで、どのコードが実行されているかを把握できます。スクリプトが、その時点の状態にある main を clone するだけの場合は、実行コードを特定できません。Iva は 2026 年 8 月 4 日から 6 日の間に 5 つのリリースを公開しました。そのため、今朝の main と今日の午後の main は同じプログラムではありません。
タグを checkout すると、git は detached HEAD 状態になります。これは問題なく動作しますが、制限を理解しておく必要があります。iva update を実行すると、checkout は更新ブランチの先頭へ進むため、固定するのは既知の開始点であり、永続的な凍結ではありません。iva version を実行すると、パッケージバージョンと git commit が表示されるため、現在の状態を常に確認できます。
意図的に新しいリリースへ移行するには、タグを一覧表示し、選択したタグを IVA_TAG に設定してから、checkout 内でインストーラーを再度実行します。
cd ~/iva
git fetch --tags
git tag --list 'v*' | sort -V | tail -5
IVA_TAG=v0.3.13
git checkout "$IVA_TAG"
bash install.sh --skip-setup
iva restart--skip-setup により、すでに動作している .env に対してウィザードが再実行されるのを防ぎます。
ウィザードの5つの手順と、入力するキー
- モデルプロバイダーとモデル。
MODEL_PROVIDERはopencode、ollama、openrouter、codexを受け付けます。ウィザードはキーをその場で検証し、契約プランで利用できるモデルを一覧表示します。 - 音声と検索。Deepgram のキーで音声メモを文字起こしします。Web 検索キー(Tavily、Exa、Parallel、または Brave)は任意です。
- @BotFather から取得した Telegram ボットトークン。
getMeエンドポイントに対して検証します。 - アクセス制御。ボットにメッセージを送り、ウィザードが
getUpdatesから数値のユーザー ID を読み取ります。 - システム設定。IANA タイムゾーン、vault ディレクトリ、ローカルポートを設定します。デフォルトは 8723 です。
「1つのコマンド」という説明では、2つの依存関係が隠れています。Iva にはモデルが付属しないため、何かに応答する前に、有料モデルプランまたは API キーが必要です。また、音声の文字起こし機能も内蔵していないため、音声メモには別のサービスが必要です。Deepgram の nova-3 モデルと DEEPGRAM_LANGUAGE=multi を使用すると言語を検出できます。新規の Deepgram アカウントには、個人利用で数か月分をまかなえるスタータークレジットが付与されます。テキストはモデルキーだけで動作します。Deepgram に依存するのは音声だけです。
ウィザードが書き込んだ内容を確認します。
grep -E '^(MODEL_PROVIDER|TELEGRAM_ALLOWED_USER_IDS|ASSISTANT_VAULT_DIR|IVA_PORT)=' ~/iva/.env
ls -l ~/iva/.envls は -rw-------、モード 0600 である必要があります。このファイルには、直前に貼り付けたすべてのキーが保存されるためです。TELEGRAM_ALLOWED_USER_IDS には数値の ID が設定されている必要があります。許可リストはフェイルクローズで動作するため、値が空の場合、Iva は誰にも応答しません。
モデルはプロセス起動時に 1 回だけ読み込まれます。MODEL_PROVIDER または .env 内のモデル名を編集しても、iva restart を実行するまで反映されません。openrouter では、モデル名は anthropic/claude-sonnet-4.5 のようなベンダーのスラッグであり、単なる名前ではありません。codex には API キーがありません。iva login が既存の ChatGPT サブスクリプションにサインインします。
毎月のIvaの運用コストはいくらですか
The data behind this chart
[
{
"plan": "Small VPS, always on",
"usd_per_month": 5
},
{
"plan": "OpenCode Go model plan",
"usd_per_month": 5
},
{
"plan": "Ollama Cloud model plan",
"usd_per_month": 20
},
{
"plan": "Deepgram voice, starter credits",
"usd_per_month": 0
},
{
"plan": "Tavily web search, free tier",
"usd_per_month": 0
},
{
"plan": "Cheapest complete setup",
"usd_per_month": 10
}
]以下は2026年8月時点の公表定価であり、実測値ではありません。小規模な VPS の料金は 5 米ドル、OpenCode Go プランは 5 ドルです。これが最も安い完全な構成で、月額は約 10 ドルです。Ollama Cloud は月額 20 ドルのもう1つの定額オプションです。プラン料金に加えて、最先端モデルの利用には従量料金がかかります。Deepgram のスタータークレジットが残っている間、音声の料金は 0 です。
OpenRouter は従量課金のため、ここには記載していません。請求額は利用量に応じて変わります。特に注意が必要な選択肢です。131072 トークンのコンテキストウィンドウを毎回のターンに引き継ぐアシスタントでは、定額プランよりも短期間で高額になる可能性があります。コンテキストウィンドウの変数には、モデルの実際のサイズを設定してください。過大な値を設定すると、トークンを無駄に消費するだけです。
2 つのサービスと 2 つのタイマー
iva.serviceはエージェント自体を実行します。iva-telegram-poll.serviceは Telegram と通信する long polling ブリッジを実行します。iva-memory-doctor.timerは 05:00 に実行され、vault に対して夜間メンテナンス処理を行います。iva-update-check.timerは 10:00 に実行され、新しい release が存在するか確認します。iva-telegram-userbot.serviceは、オプションの Telethon プロキシを設定した場合にのみ存在します。
iva status
systemctl --user status iva.service iva-telegram-poll.service
systemctl --user list-timers
iva logs polliva status は、2 つのサービスと 2 つの watchdog タイマーの状態を表示します。systemctl --user list-timers は各タイマーの次回実行時刻を表示します。これにより、memory doctor が今夜実際に実行されることを確認できます。2 つのサービスはどちらも active (running) の状態になっている必要があります。一方がループして再起動している場合は、journalctl --user -u iva.service -n 100 で原因を確認できます。
デバッグ時には、この分離が重要です。ブリッジが稼働して polling を続けていても、エージェントが停止している場合があります。その場合、Telegram はメッセージを受け付けますが、応答は返りません。iva logs poll はブリッジを追跡し、iva logs はエージェントを追跡します。2 つのログを確認すれば、どちらの部分に問題があるかを特定できます。
Obsidian vault の保存場所とバックアップ方法
ASSISTANT_VAULT_DIR はインストールディレクトリ内の vault をデフォルトで使用するため、メモリは ~/iva/vault に保存されます。これはコードとは別の独立した git リポジトリです。そのため、メモを変更せずに Iva を更新できます。
vault/CORE.mdには、長期的に保持する事実と継続的な設定を保存します。上限は 1200 文字で、すべての system prompt に含まれます。vault/daily/YYYY-MM-DD.mdはその日のトランスクリプトで、追記専用として扱われます。vault/cards/には、連絡先、プロジェクト、決定事項、アイデア、メモの型付きカードを保存します。vault/summaries/daily/、weekly/、monthly/、yearly/にはロールアップを保存します。vault/attachments/には日付ごとのファイルを保存し、vault/.graph/にはリンクグラフを保存します。vault/schema.jsonではカードの種類と減衰ルールを定義します。
ロールアップはプロセス内のスケジュールに従って実行されます。04:00 の日次処理では、前日のトランスクリプトをカードと要約に変換し、CORE.md を書き換えます。その後、週次、月次、年次の処理が順に内容を圧縮します。05:00 には memory doctor がモデルを使わずに決定的な処理を実行します。スキーマを適用し、リンクグラフを再構築し、インデックスを再生成してから、commit と push を実行します。
この push がバックアップになります。ここを見落とす人が多くいます。vault に git remote がない場合、doctor は gh を使用して private GitHub リポジトリの作成を試みます。そのためには、認証済みの GitHub CLI が必要です。
gh auth login
systemctl --user start iva-memory-doctor.service
cd ~/iva/vault && git log --oneline -3今日の日付の commit があれば、その処理が実行され、vault が commit 済みであることを示します。ログに gh not available の警告がある場合は逆です。vault は保守されていますが、サーバーの外部には保存されていません。そのため、VPS が停止するとメモリも失われます。
自分で管理するコピーも保管してください。
tar czf ~/iva-vault-backup.tgz -C ~/iva vaultscp を使用して、そのファイルをサーバー外へコピーしてから、サーバー上のファイルを削除します。Obsidian でメモリを読むには、vault リポジトリの clone を Obsidian で指定します。Wikilinks、backlinks、graph view はそのまま動作します。カードと CORE.md を手動で編集しても問題ありません。MOC.md と .graph/ は変更しないでください。夜間処理によって両方とも再生成されるためです。
Vault を生活記録として扱う
そのディレクトリには、借りているマシン上で、あなたが何を話し、誰に会い、何を決めたかが日付付きで記録されています。ここから 2 つの点が分かります。
セルフホスティングで移動するのは保存先であり、処理ではありません。すべての会話はモデルプロバイダーに送られ、すべての音声メモは Deepgram に送られます。Vault はあなたのものです。しかし、リクエストが、それを処理する企業から見えなくなるわけではありません。自分の VPS 上で Mem0 メモリサーバーを運用する場合のように、メモリ層を自分で運用しても構成は同じです。保存先はローカルでも、モデル呼び出しは外部に送られます。第三者に渡すには機微すぎる内容は、チャットに入力しないでください。
そのアカウントがアクセスできる範囲は、Vault 全体です。Iva のツールは Node の fs と child_process を使ってホスト上で直接実行され、Docker も sandbox も使用しません。そのため、乗っ取られた会話ターンには、サービスユーザーが持つ権限がそのまま与えられます。これが、インストール後にそのアカウントが sudo を保持しない理由です。また、allowlist は見た目以上に重要です。allowlist は、どのユーザーのメッセージをサーバー上のコマンドとして実行するかを決めるゲートだからです。何も公開せずに手元でアシスタントを使いたい場合は、チャットクライアントが通常は公開エンドポイントが担う役割を代替する、スマートフォンからセルフホストの Hermes エージェントに接続する構成と同じです。
動作しない場合と表示されるメッセージ
ビルドが停止し、終了コード 137 になる。 カーネルの out-of-memory killer がビルドを強制終了しています。インストーラーが swap を追加するのは、RAM が 1.5 GB 未満で、swap が存在しない場合だけです。そのため、自分で swap を追加してから、インストーラーを再実行してください。
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
free -hFailed to connect to bus。 すべての systemctl --user コマンドは、シェルにユーザーセッションバスがない場合にこのメッセージを表示します。これは sudo -iu iva が提供するものです。そのユーザーで通常の SSH セッションを開くか、コマンドの実行前に XDG_RUNTIME_DIR=/run/user/$(id -u iva) を export してください。
ボットが応答しない。 TELEGRAM_ALLOWED_USER_IDS が空で、allowlist は fail closed になっています。ボットにメッセージを送信してください。ボットは数値 ID だけを返信します。その ID を .env に設定し、iva restart を実行してください。
iva config の直後にボットが応答しなくなる。 ウィザードは ASSISTANT_HOST を更新せずに IVA_PORT を変更することがあります。そのため、bridge は応答するプロセスがないポートに接続します。2 つの行を比較してから、再起動してください。
grep -E '^(IVA_PORT|ASSISTANT_HOST)=' ~/iva/.env
iva restartボイスメッセージに応答がない。 Telegram の Bot API は 20 MB を超えるファイルのダウンロードを拒否します。そのため、bridge は長い音声を受信できず、Deepgram に送信するデータもありません。送信前にファイルを分割してください。
ffmpeg -i long.ogg -f segment -segment_time 600 -c copy part-%02d.oggターンが停止し、応答しない。 停止したワークフローの状態は再起動後も残り、自動的に再キューされます。そのため、再起動だけでは解消しません。iva reset はその状態を隔離し、両方のサービスを再起動します。チャットで /new を送信すると、新しい会話が始まります。
Ubuntu 24.04 で Chromium が起動しない。 Ubuntu 24.04 は AppArmor により、権限のない user namespace をブロックします。そのため Chromium 自身の sandbox を起動できず、agent-browser が失敗します。インストーラーは "--no-sandbox" を ~/.agent-browser/config.json に書き込むことで回避します。この設定が存在することを把握しておいてください。ブラウザーの分離レベルが下がるため、このアカウントには Iva 以外の所有物を持たせないことが重要です。
FAQ
Iva をセルフホストする場合、ドメインまたは開放ポートは必要ですか?
いいえ。Iva はロングポーリングで Telegram と通信します。iva-telegram-poll.service が getUpdates を呼び出して待機するため、すべての接続はサーバーからのアウトバウンド接続です。外部からサーバーへ到達できる必要はないため、DNS レコードも証明書も不要です。エージェント自身の HTTP ポート 8723 は 127.0.0.1 にバインドされ、プロジェクトのドキュメントでも外部公開しないよう指示されています。SSH だけを許可し、それ以外を許可しないファイアウォール設定が適切です。
Iva の月額運用費はいくらですか?
公開されている 2026 年 8 月の定価では、5 ドルの小規模 VPS と、最安の定額モデルプラン 5 ドルを合わせると、月額約 10 US ドルです。Ollama Cloud の場合は 20 ドルで、これに最先端モデルの料金が加算されます。Deepgram のスタータークレジットで、最初は音声処理をまかなえます。Web 検索プランにも無料枠があります。OpenRouter は従量課金のため、固定の月額料金はありません。
Iva はデータをどこに保存しますか。また、どのようにバックアップしますか?
デフォルトでは ~/iva/vault に保存され、ASSISTANT_VAULT_DIR で設定されます。これは、プレーンな markdown を保存する独立した非公開 git リポジトリです。保存対象は CORE.md、daily/YYYY-MM-DD.md、cards/、summaries/ です。05:00 に実行される memory doctor がコミットとプッシュを行います。ただし、リポジトリにリモートが設定されている場合にのみ有効です。そのため、セットアップ中に gh auth login を実行するか、独自のリモートを追加してください。さらに、tar czf ~/iva-vault-backup.tgz -C ~/iva vault でオフラインコピーを作成し、そのファイルをサーバー外へ移動してください。
Iva をセルフホストした場合、データは非公開ですか?
ストレージは自分で管理できます。ただし、処理はそうではありません。vault はプッシュするまでディスク上に残り、.env はサービスユーザーが所有する mode 0600 で保存されます。モデルへのリクエストと音声の文字起こしは cloud API を使用するため、メッセージはモデルプロバイダーと Deepgram を経由します。Iva は MIT ライセンスで提供されているため、送信内容を正確に確認し、変更できます。Telegram の allowlist は fail closed で動作します。つまり、TELEGRAM_ALLOWED_USER_IDS が空の場合は、あなたを含む全員がブロックされます。
Iva はどのモデルプロバイダーに対応していますか?
MODEL_PROVIDER は opencode (OpenCode Go)、ollama (Ollama Cloud)、openrouter、codex を受け付けます。OpenRouter では anthropic/claude-sonnet-4.5 のようなベンダー slug を指定でき、最も幅広いモデルを利用できます。codex は iva login で既存の ChatGPT サブスクリプションにサインインし、API key を使用しません。プロバイダーを設定し、モデルの実際のサイズに合わせて context window を設定してから、iva restart を実行してください。モデルはプロセスの起動時に 1 回だけ読み込まれるためです。