Skip to content

git worktree ごとのプレビュー環境

ブランチを切れば、環境は専用の URL ですでに動いています。人からもエージェントからも同じように扱えます。

curl -fsSL https://kobune.1024.works/install.sh | sh

kobune.toml

[project]
name = "myapp"
[runtime]
default = "docker"
[services.web]
image = "node:22"
port = 3000
command = "npm run dev"

このファイルを 1 つコミットしておけば、あとから増える worktree すべてがこれを読みます。

何が起きるか

  1. 1kobune init

    上のファイルを書き出します。リポジトリのほかの部分は変わりません。

  2. 2kobune new feature/user-auth

    worktree を作り、その環境も一緒に立ち上げます。

  3. 3https://web.feature-user-auth.myapp.localhost

    あとは開くだけです。ポート番号は誰も選んでおらず、再起動しても同じ名前で届きます。

docker compose から移ってくる場合

サービスの内容はいま書いているものと同じです。変わるのは、チェックアウト単位ではなく worktree 単位で環境ができることと、サービスごとにブランチではなくプロジェクトに属すると宣言できることです。

docker-compose.yml

services:
web:
image: node:22
command: npm run dev
ports: ["3000:3000"]
db:
image: postgres:16

kobune.toml

[services.web]
image = "node:22"
command = "npm run dev"
port = 3000
[services.db]
image = "postgres:16"
scope = "project"

kobune init --from-compose を実行すると、左のファイルから右のファイルを書き出します。最初の kobune up の前に、残された TODO を読んでください。docker compose には Kobune に対応するキーがない設定もあり、その部分は推測せずに印を付けます。

何もない状態から 2 つのプレビューまで

録画ではありません。コマンドが実際に出力する内容を、そのまま文字として描いています。

ブランチが 2 つ、URL も 2 つ。どちらも動いたままで、ポート番号は誰も選んでいません。

セッションの内容をテキストで読む
── shell-a ──
$ kobune init
╭ init ─────────────────────────────────────╮
│ created  ~/myapp/kobune.toml              │
│ project  myapp                            │
│                                           │
│ › bring the environment up with kobune up │
╰───────────────────────────────────────────╯
$ kobune up
  ✓ preparing the network
  ✓ pulling image node:22
  ✓ starting web
  ✓ waiting for web
╭ myapp / (main) ───────────────────────────╮
│ main  ~/myapp                             │
│                                           │
│ ● web  ready  https://web.myapp.localhost │
╰───────────────────────────────────────────╯
$ kobune new feature/user-auth
  ✓ creating worktree feature/user-auth
  ✓ starting web
  ✓ waiting for web
╭ myapp / feature-user-auth ──────────────────────────────────╮
│ feature/user-auth  ~/myapp.wt/feature-user-auth             │
│                                                             │
│ ● web  ready  https://web.feature-user-auth.myapp.localhost │
╰─────────────────────────────────────────────────────────────╯

── web-a ──
https://web.feature-user-auth.myapp.localhost

── shell-a ──
$ cd ~/myapp.wt/feature-user-auth
$ kobune logs -f web
  │ ready in 412 ms
  │ GET /sign-in 200

── shell-b ──
$ kobune new fix/checkout-total
  ✓ creating worktree fix/checkout-total

── shell-a ──
  │ GET /assets/app.js 200

── shell-b ──
  ✓ starting web
  ✓ waiting for web
╭ myapp / fix-checkout-total ──────────────────────────────────╮
│ fix/checkout-total  ~/myapp.wt/fix-checkout-total            │
│                                                              │
│ ● web  ready  https://web.fix-checkout-total.myapp.localhost │
╰──────────────────────────────────────────────────────────────╯

── web-b ──
https://web.fix-checkout-total.myapp.localhost

── shell-a ──
  │ POST /sign-in 302

── shell-b ──
$ kobune ls
╭ workspaces ──────────────────────────────────────╮
│ WORKSPACE           SERVICES  BRANCH             │
│ (main)              1/1       main               │
│ feature-user-auth   1/1       feature/user-auth  │
│ fix-checkout-total  1/1       fix/checkout-total │
╰──────────────────────────────────────────────────╯

できること

worktree 1 つに環境 1 つ
worktree を作れば環境ができ、削除すれば環境も消えます。覚えることはこの対応関係だけです。
ポート番号を管理しない
内部のポート番号は起動のたびに変わりますが、URL は変わりません。
使っていない環境は自動で停止
一定時間アクセスのない環境は自動的に停止し、次のリクエストで 1〜2 秒で復帰します。
名前が変わらない
web.feature-auth.myapp.localhost はブランチ名から作られるので、明日も同じ名前です。
共有すべきものは共有する
データベースはブランチではなくプロジェクトに属するものとして、全体で 1 つだけ起動できます。
トンネルで共有できる
Cloudflare Tunnel を経由して、スマートフォンやレビュアーに URL を共有できます。

エージェントも同じコマンドを使う

人が使うのと同じコマンドで、プログラムが読む部分だけ --json を付けます。失敗したときは種類の分かる終了コードが返るので、エージェントは空の応答ではなく理由を受け取ります。

AI エージェントと使う

コンテナを動かすもの

kobune.toml の [runtime] default に、次のいずれかを書きます。コンテナの手配をするのが Kobune で、実際に起動するのはランタイムです。

  • docker既定で、2 つのうち対応が手厚いほうです。docker コマンドではなく Docker API を直接呼ぶため、Docker Desktop でも OrbStack でも colima でも動きます。
  • apple利用できます。macOS 26 以降で、container system start を実行済みであることが必要です。コンテナごとに独自のアドレスが割り当てられ、ホスト側には何も公開されません。worktree が 2 つあってもポートは衝突しません。
  • firecracker対応予定です。

Kobune がやらないこと

  • 本番環境向けのデプロイツールではありません。 開発マシン上で、その所有者が操作することを前提としています。
  • コンテナランタイムではありません。 実際にコンテナを動かすのは Docker や Apple Container です。Kobune はその手配をするだけです。
  • docker compose の代替でもありません。 1 つのブランチで 1 つの環境を動かせば足りるのであれば、docker compose のほうが単純です。
仕組み

Released under the Apache License 2.0.

nightly ビルドです。リリース版ではなく、まだ安定していません。 詳しく