Your first environment
From an empty repository to a working URL. Ten minutes, most of it waiting for an image to pull.
This assumes you have followed Installation and that kobune doctor has nothing to say.
1. Describe the project
In the root of a git repository:
$ kobune init
╭ init ─────────────────────────────────────╮
│ created /path/to/myapp/kobune.toml │
│ project myapp │
│ │
│ › bring the environment up with kobune up │
╰───────────────────────────────────────────╯kobune init writes a starter file and guesses the project name from the directory. Open it and point it at something real:
[project]
name = "myapp"
[runtime]
default = "docker"
[services.web]
image = "node:22"
port = 3000
command = "npm run dev"Three things matter here:
portis the port your app listens on inside the container. Kobune never asks for a host port; there is none to know.commandreplaces the image's own command. Leave it out to use the image's default.- Your worktree is mounted at
/workspace, which is also the working directory. Sonpm run devruns against the branch's code.
Commit it. kobune.toml belongs in the repository — every worktree reads the same one.
2. Start it
$ kobune up
✓ preparing the network
✓ pulling image node:22
✓ starting web
✓ waiting for web
╭ myapp / (main) ───────────────────────────╮
│ main /path/to/myapp │
│ │
│ ● web ready https://web.myapp.localhost │
╰───────────────────────────────────────────╯The main worktree leaves the workspace label out of its URL, so it is web.myapp.localhost rather than web.main.myapp.localhost.
That last step — waiting for web — is Kobune waiting for your app to answer, not just for the container to exist. The two are not the same, and a curl immediately after a container starts usually fails.
3. Reach it
$ curl -sS --fail-with-body https://web.myapp.localhostOr ask for the URL and use it:
$ kobune url web
https://web.myapp.localhostWith a service named, kobune url prints one line and nothing else, so it pipes and substitutes cleanly. This is the command to reach for instead of writing a URL by hand. Leave the name out and it lists them all.
Certificate errors
curl exiting with code 60 means the local CA is not trusted yet. Run kobune doctor — it prints the command to fix it. This is the single most common thing to hit first.
4. Branch, and get a second environment
Here is the part that makes worktrees worth it:
$ kobune new feature/user-auth
✓ creating worktree feature/user-auth
✓ starting web
✓ waiting for web
╭ myapp / feature-user-auth ──────────────────────────────────╮
│ feature/user-auth /path/to/myapp.wt/feature-user-auth │
│ │
│ ● web ready https://web.feature-user-auth.myapp.localhost │
╰─────────────────────────────────────────────────────────────╯Both environments are now running, on separate URLs, from separate checkouts. Nothing was stopped, and no port was chosen by anyone.
The worktree lands in ../myapp.wt/feature-user-auth — beside the repository rather than inside it, so editors and searches do not pick it up twice.
$ kobune ls
╭ workspaces ────────────────────────────────────╮
│ WORKSPACE SERVICES BRANCH │
│ (main) 1/1 main │
│ feature-user-auth 1/1 feature/user-auth │
╰────────────────────────────────────────────────╯5. Work in it
$ cd ../myapp.wt/feature-user-authFrom inside a worktree, commands act on that workspace by default:
$ kobune logs web -f # follow this branch's logs
$ kobune exec web -- npm test # run the tests inside its container
$ kobune status # what is running, and whereFrom anywhere else, name it with -w:
$ kobune logs -w feature-user-auth web6. Leave it alone
Do nothing for a while and the environment stops itself. Come back and the first request starts it again:
$ curl -sS https://web.feature-user-auth.myapp.localhost
# a second or two, then the responseYou never have to run kobune up again for a branch you are still using. This is what makes creating worktrees cheap: an idle one costs nothing.
7. Clean up
$ kobune rm -w feature-user-authRemoves the worktree and its containers. The branch stays — this is not git branch -d.
Next
- Configuration — several services, health checks, volumes
- Everyday workflow — the commands you will actually use
- A preview per branch — the same ground, worked through on a real app