SSD Nodes Learn Hosting plans →
ガイド Matt Connor著者 Matt Connor ・更新日 2026-08-28

KiroCrewをVPSでセルフホストする方法

KiroCrewをVPSで常時稼働させる手順です。Dockerでバージョンを固定し、systemd、SSH、バックアップ、ロールバックで再起動後もメモリと03:00のジョブを守ります。

ノートパソコンではなくVPSでKiroCrewをセルフホストする理由

KiroCrewのセルフホストは、スリープしないマシンで運用して初めて効果があります。そのため、適した配置先はVPSであり、ノートパソコンではありません。KiroCrewはセッション履歴、意味メモリ、スケジュール済みジョブ、承認キューをディスクに保存し、プロセスの再起動時にそれらをすべて読み込みます。スケジュール済みジョブの実行時刻である03:00にプロセスが動作していなければ、これらの機能は役に立ちません。閉じたノートパソコンではプロセスは動作しません。

KiroCrewはKiro teamが開発するオープンソースのエージェントワークスペースで、ライセンスはApache 2.0です。最初の一般公開リリースは2026年8月上旬に提供されました。gatewayと呼ばれる1つのプロセスが状態を管理し、port 5476でWebダッシュボードを提供します。ダッシュボード、kirocrew CLI、またはSlackなどのチャットチャンネルからgatewayに接続します。セルフホストするのはgatewayだけです。そのため、このガイドでは、gatewayを稼働させ続ける方法、パブリックインターネットから隔離する方法、問題のあるアップグレード後に復旧できる状態にする方法を説明します。

開始前に、2点把握しておく必要があります。KiroCrewはkiro-cliを使用します。kiro-cliでは、Kiro accountによる初回のサインインが必要です。また、エージェントの推論にはKiro planの料金が発生するため、2026年8月時点ではオフライン構成ではありません。このプロジェクトは公開からまだ数週間しか経過していません。いずれロールバックが必要になることを前提に、ロールバックできる方法でインストールしてください。これまでサーバー上でエージェントを実行したことがない場合は、VPSでコーディングエージェントを実行するで、このガイドの前提となる基本事項を確認できます。サーバーよりもエージェントのほうに不慣れであれば、まずエージェントループ、そのツール、メモリの実際の仕組みを学ぶと、以下の選択を単なる決まり文句ではなく、判断として理解しやすくなります。

KiroCrew に必要なものと状態の保存場所

ネイティブインストールには Python 3.10 以降が必要です(プロジェクトでは 3.12 を推奨しています)。ダッシュボードをソースからビルドする場合は Node.js 18 以降も必要です。また、kiro-cli も必要です。これは初回起動時にインストールされ、サインインまで自動的に行われます。コンテナインストールでは、ホスト側にこれらは必要ありません。必要なのは Docker だけです。これが、コンテナインストールを優先する主な理由です。

状態は ~/.kiro/crew に保存されます。KIROCREW_HOME 環境変数を設定すると、保存先を変更できます。内部には次のものが含まれます。

  • config.json: gateway の設定とチャットチャネルの認証情報。
  • .env: Secret。
  • workspace/memory/: 環境設定、プロジェクトメモ、チャット履歴。
  • memory.dbmemory_index.db: セマンティックインデックスと全文検索インデックス。
  • models/: 初回実行時にダウンロードされる埋め込みモデル。
  • gateway.logsecurity_events.jsonl: 実行時ログとセキュリティイベントログ。

このディレクトリがインストール内容そのものです。これを新しい VPS にコピーすれば、エージェントを移行できます。そのため、以下のバックアップの章はインストールの章より重要です。

RAM よりもディスク容量を基準に計画してください。gateway は Python プロセスです。ホストに実際に負荷をかけるのは、エージェントが実行する処理、ビルド、テストスイートです。状態ディレクトリはチャット履歴に応じて増加します。埋め込みモデルも初回起動時に取得されます。そのため、プロジェクトの最初の月に公開された数値をそのまま使わず、数週間運用した後に du -sh ~/.kiro/crew で実際の環境を測定してください。各ワーカーに専用のコンテナとブラウザーを割り当てるランタイムとは対照的です。その場合、OpenBot の AI ワーカーをセルフホストする構成では、ディスク容量より先に RAM 容量が問題になります。

使用するインストール方法

このプロジェクトでは、3 つのインストール方法が公開されています。1 行のインストーラーは wheel を取得し、kirocrew を PATH に追加します。

curl -fsSL https://download.crew.kiro.dev/cli.sh | sh

channel フラグと version フラグを指定します。

curl -fsSL https://download.crew.kiro.dev/cli.sh | sh -s -- --channel insider
curl -fsSL https://download.crew.kiro.dev/cli.sh | sh -s -- --version 0.1.3

コンテナイメージは ghcr.io/kirodotdev/kirocrew で公開されており、すべてのタグで linux/amd64linux/arm64 に対応しています。ソースからのビルドには git clonemake build が必要です。これはコードを変更する人向けであり、実行する人向けではありません。

コンテナを使用してください。ネイティブインストールでは、Python パッケージ、Node、kiro-cli が他のサービスを実行している同じホストに配置されます。そのため、アップグレードに失敗すると、手作業で元の状態に戻す必要があります。コンテナでは、ランタイムを 1 つのイメージに、状態を 1 つのボリュームに保持できます。ロールバックはタグの変更と再起動だけで済みます。

イメージは stable ではなくリリースタグに固定する

プロジェクト独自の例では、stable タグを使用しています。

docker run -d --name kirocrew \
  -p 127.0.0.1:5476:5476 \
  -v kirocrew-home:/home/kirocrew \
  ghcr.io/kirodotdev/kirocrew:stable

stable は可変タグです。常に最新の安定版を指すため、次回の pull で、選択していないバージョンに実行中のバージョンが変わる可能性があります。また、そのタグからは、どのバージョンだったかを確認できません。バージョンタグは不変なので、いずれか1つに固定してください。2026年8月6日時点の最新リリースは 0.1.3 で、2026年8月5日に公開されています。nightly タグもありますが、このように公開から間もないプロジェクトでは、今朝コードが変更されたことを意味します。

/opt/kirocrew/compose.yaml を記述します。

services:
  kirocrew:
    image: ghcr.io/kirodotdev/kirocrew:0.1.3
    container_name: kirocrew
    restart: unless-stopped
    ports:
      - "127.0.0.1:5476:5476"
    volumes:
      - kirocrew-home:/home/kirocrew

volumes:
  kirocrew-home:

起動したら、イメージ自身の HEALTHCHECK にも使用されているヘルスエンドポイントを確認します。

cd /opt/kirocrew
docker compose up -d
docker compose ps
curl -s http://127.0.0.1:5476/api/health

docker compose ps は、1分程度以内にコンテナが healthy であることを報告するはずです。/api/health はトークンなしで応答します(/api/live/api/ready も同様です)。そのため、これらをプローブとして使用できます。状態が starting のままの場合は、何も変更せずに docker logs kirocrew を確認してください。初回の実行では embedding model をダウンロードするため、接続が遅いと初回起動に時間がかかります。

systemd で稼働を維持する

restart: unless-stoppedは、Docker 自体がブート時に起動する限り、クラッシュ後や再起動後にコンテナを復旧します。unit ファイルを使うと、その依存関係を明示でき、バックアップ前にスタック全体を停止するコマンドも 1 つにまとめられます。一般的な構成については、ブート時に Docker Compose スタックを起動するで説明しています。KiroCrew では、/etc/systemd/system/kirocrew.serviceのように構成します。

[Unit]
Description=KiroCrew gateway
Requires=docker.service
After=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/kirocrew
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now kirocrew
systemctl status kirocrew

systemctl status kirocrewactive (exited)になるはずです。これは、この unit が正常に動作している結果です。Type=oneshotRemainAfterExit=yesを指定するのは、この場合は正しい設定です。docker compose up -dはコンテナの起動直後に返るためです。systemd が追跡するのはフォアグラウンドプロセスではなく、スタックが起動している状態です。代わりにType=simpleと記述すると、systemd はコマンドがすぐに終了したと判断し、サービスを停止状態として扱います。その後、Restart=の設定に応じて処理を諦めるか、再起動を繰り返します。ネイティブインストールでは、プロジェクトが同等のkirocrew service installを提供しています。これは/etc/systemd/system/kirocrew.serviceを書き込み、ユーザーとしてゲートウェイを実行します。両方の unit を実行しないでください。このトピックの詳しい説明は、VPS 上の systemd サービスとタイマーにあります。復旧しない unit は、通知する仕組みを設定しない限り無言のままです。そのため、OnFailure=ハンドラーを追加して、自分の ntfy サーバーにアラートを送信するようにします。そうすれば、実行されなかったスケジュールジョブではなく、スマートフォンでゲートウェイの停止を確認できます。

初回実行: サインインしてダッシュボードトークンを取得する

コンテナはゲートウェイを起動しますが、エージェントランタイムではまだサインインしていません。コンテナ内でサインインします。

docker exec -it kirocrew kiro-cli login

デバイスコードと、自分のブラウザーで開く URL が表示されます。続いて、ダッシュボードトークンを発行します。

docker exec kirocrew kirocrew token --ttl 2h

ダッシュボードの URL は http://localhost:5476/?token=<the token> です。トークンには有効期限があります。セッションの既定値は 1 時間で、文書化されている最大値は 20 時間です。ダッシュボードが空白で表示される場合や、すぐにサインアウト画面へ戻される場合は、通常、トークンの有効期限が切れています。その場合は別のトークンを発行してください。トークンをチケットやチャットメッセージに貼り付けないでください。トークンを保持する人は、エージェントを操作できるためです。

SSH 経由でダッシュボードにアクセスし、ポート 5476 は公開しない

プロジェクトの例にあるバインドアドレスをもう一度確認してください: -p 127.0.0.1:5476:5476。コンテナ内では、ポートマッピング経由で到達できる必要があるため、ゲートウェイは 0.0.0.0 で待ち受けます。ただし、マッピング自体はホストの loopback に対してのみ公開します。127.0.0.1: プレフィックスを削除すると、そのポートをスキャンする誰もがゲートウェイへアクセスできる状態になります。ファイアウォールルールでも防げません。Docker は DNAT ルールを書き込みます。このルールは ufw のフィルタリングより前に評価されるため、ufw deny 5476 では公開済みポートを制御できません。ufw を迂回する Docker のポートで、この仕組みを説明しています。

ノートパソコンから SSH でポートを転送します。

ssh -N -L 5476:127.0.0.1:5476 you@your-server.example.com

このコマンドを実行したまま、ローカルで http://localhost:5476/?token=<the token> を開きます。接続のたびに転送を自動化するには、~/.ssh/config に設定します。

Host your-server.example.com
    LocalForward 5476 127.0.0.1:5476

ノートパソコンですでにポート 5476 が使用されている場合は、左側の番号だけを変更します: ssh -N -L 45476:127.0.0.1:5476 you@your-server.example.com。その後、http://localhost:45476/?token=... にアクセスします。2 つ目のエージェントが同じサーバーを共有すると、すぐにこのような転送を重ねることになります。セキュリティスキャン用の open-kritt のセルフホスティングにより、同じサーバー上のポート 5173 に、別の loopback 専用ダッシュボードが追加されるためです。

トンネル経由では、次の動作に注意してください。ゲートウェイは転送されたリクエストをリモートからのものとして扱うため、ダッシュボードの設定書き込みエンドポイントと Secret 表示エンドポイントはそれらを拒否します。SSH 経由で設定を保存できない場合、それはバグではなく、この動作によるものです。ホスト上で設定を直接編集します。

docker cp kirocrew:/home/kirocrew/.kiro/crew/config.json .
# edit config.json here
docker cp config.json kirocrew:/home/kirocrew/.kiro/crew/config.json
docker exec -u 0 kirocrew chown kirocrew:kirocrew /home/kirocrew/.kiro/crew/config.json
docker restart kirocrew

スマートフォンからのアクセスについて、プロジェクトは Tailscale の tailscale serve を案内しています。これにより、ダッシュボードを公開ホスト名ではなく、自分の tailnet 内に限定できます。公開リバースプロキシよりもこちらを優先してください。トークンは URL に含まれ、その URL は通過するすべてのアクセスログに記録されます。このルールはポート自体ではなく、その背後で動作するものに関するものです。たとえば、Jellyfin ライブラリを閲覧可能な 90 年代ビデオストアとして再構築する Halcyon は他の人が開くことを前提としており、リバースプロキシの対象として適しています。一方、サーバー上でコマンドを実行できるゲートウェイは対象にしないでください。

エージェントの影響範囲を可能な限り小さくする

コンテナは初回起動時に sandbox のサポート状況を確認し、その結果によってエージェントが実行できる操作を決定します。namespace による分離が利用できる場合、エージェントのサブプロセスは分離された環境で実行されます。利用できず、KIROCREW_ALLOW_UNSANDBOXED=1も設定されていない場合は、分離なしで実行せず、実行自体を拒否します。そのため、ゲートウェイは正常に見えるのにすべてのタスクが停止する場合は、通常これが原因です。この判定結果は初回実行時のdocker logs kirocrewに記録されます。プロジェクトでは、適用できる seccomp (secure computing mode) プロファイルも公開しています。

curl -fsSL https://raw.githubusercontent.com/kirodotdev/KiroCrew/main/docker/seccomp/kirocrew-seccomp.json \
  -o /opt/kirocrew/kirocrew-seccomp.json
    security_opt:
      - seccomp:./kirocrew-seccomp.json

KIROCREW_ALLOW_UNSANDBOXED=1を設定する場合は、何が変わるのかを明確にしてください。エージェントとサーバーの間に残る境界は、コンテナだけになります。プロジェクトの警告をそのまま繰り返します。エージェントに直接渡せない host のパスをマウントしないでください。具体的には、Docker socket、/の bind mount、別のサービスのデータを保持するディレクトリは使用できません。

それ以外は、コマンド実行を許可するすべてのエージェントに適用される基本方針です。認証情報の権限は、必要な1つのリポジトリまたは1つの bucket に限定してください。アカウント全体の権限を持つ個人用 token は使用しないでください。専用 user として実行し、その home には他のデータを置かないでください。これは、VPS で最小権限の user を使用するための方法です。エージェントがコードを書いて、そのコードを実行する場合は、壊しても問題ないマシンを割り当ててください。コーディングエージェント用の使い捨て VMは、この compose file のどの flag よりも強固な境界になります。問題が起きたら環境を修復するのではなく、削除できるためです。同じ考え方が、VPS で OpenClaw を安全に実行する場合や、VPS で Hermes agent を self-hosting する場合にも当てはまります。ツールも影響範囲に含まれます。エージェントに web search を渡すと、取得するすべてのページが信頼できない入力になります。そのため、独自の SearXNG instance を参照させることは、接続方法だけでなく prompt injection に関する判断でもあります。スケジュール実行では、就寝中にも推論料金が発生し、Kiro plan に請求されます。そのため、夜間ジョブを追加する前に、VPS 上の AI agent のコストを制御するで説明している上限を設定してください。

アップグレードの前に毎回 state volume をバックアップする

最初に実際の volume 名を確認します。Compose は名前付き volume に project 名を付けます。project 名の既定値はディレクトリ名です。そのため、/opt/kirocrew/compose.yamlkirocrew-home として宣言した volume は kirocrew_kirocrew-home として作成されます。

docker volume ls

コピーする前に gateway を停止します。memory.dbmemory_index.db は SQLite データベースです。書き込み中のデータベースをコピーすると、書き込み途中のトランザクションが含まれ、復元後にファイルが破損することがあります。プロジェクト独自の移行手順にも同じことが記載されています。gateway を停止している間だけ memory を移動します。この停止を先に行うルールは KiroCrew 固有ではありません。photo server も同じホストで運用している場合は、PhotoPrism と Immich の比較に、それぞれに必要な正確なバックアップコマンドを記載しています。

sudo systemctl stop kirocrew
docker run --rm -v kirocrew_kirocrew-home:/data:ro -v "$PWD":/backup \
  alpine tar czf /backup/kirocrew-2026-08-06.tgz -C /data .
sudo systemctl start kirocrew

アーカイブをホストの外部へコピーします。復元時は、container を停止し、tar czf の代わりに tar xzf を指定して同じコマンドを実行します。

sudo systemctl stop kirocrew
docker run --rm -v kirocrew_kirocrew-home:/data -v "$PWD":/backup \
  alpine tar xzf /backup/kirocrew-2026-08-06.tgz -C /data
sudo systemctl start kirocrew

新しいホストへの移行は、現在のホスト上での復元とは別の作業です。プロジェクトでは、その手順を明確に指定しています。workspace/memory/ 配下の chat history と project notes は引き継ぎます。2 つのデータベースファイルと config.json も引き継ぎます。PID ファイル、security event log、.env は旧ホストに依存するため移行せず、新しいホストで secrets を再入力します。

不適切なアップグレードをロールバックする方法

アップグレード自体は短時間で完了します。バージョンを固定しているため、安全に実施できます。最初にバックアップを取得してから、タグを変更します。

sudo systemctl stop kirocrew
# take the backup here, as above
sudo nano /opt/kirocrew/compose.yaml   # set the new image tag
sudo systemctl start kirocrew
docker compose -f /opt/kirocrew/compose.yaml ps
curl -s http://127.0.0.1:5476/api/health

docker compose up -dはイメージがまだサーバー上にない場合に取得するため、タグの編集だけでアップグレード全体が完了します。ロールバックも、以前の番号を指定して同じ手順を実行します。バージョンタグは変更されないため、アップグレード前とまったく同じイメージを使用できます。

バイナリは問題なくロールバックできます。問題になる可能性があるのは状態です。新しいゲートウェイが config.jsonを書き換えたり、メモリデータベースを古いゲートウェイでは読み取れない形式に移行したりする可能性があります。2026 年 8 月時点で、ダウングレード手順は文書化されていません。そのため、古いイメージが起動した後に動作が不安定になった場合は、原因を調査しないでください。停止し、アップグレード前に取得したバックアップを復元してから、もう一度起動します。これが最初にバックアップを取得する理由です。アップグレードを先に実行し、バックアップを後回しにする習慣が、この導入から間もないプロジェクトで通用しない理由でもあります。

ここで証明されていないこと

このソフトウェアがまだ新しいことを正しく認識してください。執筆時点でバージョン 0.1.3 のリリースから数日しか経過していません。リリースノートも移行手順ではなく、自動生成された changelog へのリンクです。アップグレードの実績もまだありません。このガイドの内容は長期運用で確認された結果ではありません。そのため、メモリ使用量の増加、データベースサイズ、スケジューラーの信頼性は、前提にせず、自分の環境で測定してください。

依存する前に、2 つの動作を自分で確認する価値があります。1 つ目は、downgrade したバージョンが新しいバージョンによって書き込まれた state を読み込めるかどうかです。障害対応中ではなく、影響が出ない時点で volume のコピーを使って試してください。2 つ目は、scheduled job の実行時刻に Kiro の sign-in が期限切れになった場合に gateway がどう動作するかです。どちらも、若いプロジェクトでは release 間にひっそり修正される可能性がある粗さです。今のうちに確認しておけば、いずれも簡単に検証できます。

FAQ

KiroCrew のダッシュボードがサーバーのパブリック IP で開かないのはなぜですか?

公開されている例では、ポートが loopback にバインドされているためです。-p 127.0.0.1:5476:5476 はコンテナのポートをホストの loopback アドレスだけにマッピングします。これは意図した動作です。ssh -N -L 5476:127.0.0.1:5476 you@your-server で SSH 経由でポートを転送し、ノート PC で http://localhost:5476/?token=<token> を開いてアクセスします。127.0.0.1: プレフィックスを削除して外部からアクセス可能にすると、ゲートウェイがパブリックインターネットに公開されます。Docker の公開ポート用 DNAT ルールは ufw がトラフィックをフィルタリングする前に評価されるため、ファイアウォールルールだけでは制限できません。

KiroCrew はデータをどこに保存しますか。何をバックアップすべきですか?

すべてのデータは ~/.kiro/crew 配下にあり、これはコンテナイメージ内では /home/kirocrew/.kiro/crew です。KIROCREW_HOME により保存先を変更できます。ゲートウェイを停止した状態で、ディレクトリ全体または Docker volume 全体をバックアップしてください。memory.dbmemory_index.db は SQLite データベースです。そのため、ゲートウェイによる書き込み中に取得したコピーは不整合になる可能性があります。新しいホストへ移行する場合は、workspace/memory/、2 つのデータベースファイル、config.json を移行します。一方、PID ファイル、セキュリティイベントログ、.env は旧ホストに属するため、移行しません。

stable タグとバージョンタグのどちらを使用すべきですか?

バージョンタグを使用してください。stable はリリースされるたびに移動するため、次回の pull 後に実行するバージョンが変わる可能性があります。また、タグだけでは実行中の内容を判断できません。0.1.3 などのバージョンタグは不変です。これによりロールバックが確実に機能します。以前のバージョン番号に戻せば、同一のイメージを取得できます。2026 年 8 月 6 日時点での最新リリースは 0.1.3 です。

エージェントがコマンドの実行をすべて拒否するのはなぜですか?

コンテナは初回起動時にサンドボックスのサポートを検査します。エージェントのサブプロセスを隔離できず、KIROCREW_ALLOW_UNSANDBOXED=1 も設定されていない場合、制限なしで実行する代わりに、サブプロセスの実行を拒否します。そのため、ゲートウェイは正常に見えても、すべてのタスクが停止します。docker logs kirocrew で、初回実行時に決定されたサンドボックスの状態を確認できます。この変数を設定すると、エージェントとホストの間にある境界はコンテナだけになります。設定する場合は、エージェントに直接渡してもよいもの以外をマウントしないでください。

KiroCrew をセルフホストするには Kiro アカウントが必要ですか?

はい。2026 年 8 月時点では必要です。KiroCrew は Apache 2.0 の下で提供される free software ですが、kiro-cli を使用します。kiro-cli には 1 回限りのサインインが必要で、エージェントの推論には Kiro プランの料金が適用されます。コンテナ内で docker exec -it kirocrew kiro-cli login を実行し、ブラウザーで device code を承認してください。サインインが完了するまでは、ゲートウェイが起動してダッシュボードも読み込まれますが、エージェントには接続するモデルがありません。