Run apps side by side
Three worktrees of the same web app all want port 3000. In Offsite each worktree has its own window of 100 ports, and every app you run in it gets a port from that window. Three versions of your app run at once, and the main checkout keeps its own ports next to them.
Your app’s port
Section titled “Your app’s port”A Run entry starts your app with $OFFSITE_PORT, the
entry’s own port:
npm run dev -- --port $OFFSITE_PORTEach entry keeps its port for the life of the worktree, so adding or reordering entries never moves an app that is running.
Several apps
Section titled “Several apps”A worktree with a web app and an API gives each entry its own port, and every entry sees
the others’ ports as $OFFSITE_RUN_<NAME>_PORT, the name in capitals with - as _:
API_URL=http://localhost:$OFFSITE_RUN_API_PORT npm run dev -- --port $OFFSITE_PORTThe web of each worktree talks to the api of the same worktree.
- web:24100→ $OFFSITE_RUN_API_PORT
- api:24101
- web:25700→ $OFFSITE_RUN_API_PORT
- api:25701
$OFFSITE_RUN_API_PORT, so two copies of the app run side by side without crossing.Run from the header
Section titled “Run from the header”The worktree’s header has a Run button for its app; with several apps, one Run
button whose popover lists them. It starts the entry in your login shell with the
worktree’s environment, so nvm and other shell functions work. The popover shows its terminal and the port the app
listens on, with a copy button, and offers Stop and Run again. When an app exits
with an error, Ask an agent hands the failure to an agent.
When another process already listens on the port, the start goes ahead and a note names that process and its pid.
The column card shows Running, Stopped or Exited with the exit status, with the names of the apps when there are several.
The Browser card
Section titled “The Browser card”A Browser card in a worktree opens the repository’s start page on the worktree’s first
port, the one its first Run entry gets. With http://localhost:3000 as the start page, a
worktree whose window starts at 24100 opens http://localhost:24100. Set the start page in the Browser card’s settings;
see Browser.
The agent runs it too
Section titled “The agent runs it too”The worktree’s agent starts apps through its worktree_run tool. They run in the same
Run terminals you see in the header, on the same ports. Its brief asks it to start its own
dev server, database or simulator instance for tests, to leave processes it did not start
alone, and to stop what it started before it reports.
Databases and containers
Section titled “Databases and containers”Name what a worktree creates outside its folder after its port window, and drop it in Clean up:
docker compose -p bloom-$OFFSITE_PORT_BASE up dbEach worktree then has its own container, and deleting the worktree removes it.
The environment
Section titled “The environment”Every agent, terminal, setup step and run entry in a worktree gets:
| Variable | Value |
|---|---|
OFFSITE_PORT_BASE, OFFSITE_PORT_BASE_END | the worktree’s port window, 100 ports between 20000 and 29999 |
OFFSITE_WORKTREE_PATH | the worktree’s folder |
OFFSITE_WORKTREE_BRANCH | its branch |
OFFSITE_WORKTREE_BASE_COMMIT | the commit it started from |
OFFSITE_SOURCE_CHECKOUT | the main checkout |
A run entry also gets:
| Variable | Value |
|---|---|
OFFSITE_PORT | this entry’s port |
OFFSITE_RUN_<NAME>_PORT | the port of each entry, by name |
OFFSITE_RUN_NAME | this entry’s name |
The window is picked from the branch name when the worktree is created and stays with it. Offsite picks a window no other worktree or main checkout holds.
The main checkout takes its own window the first time its Setup or Run needs one. There,
Setup and Run get OFFSITE_PORT_BASE, OFFSITE_PORT_BASE_END and
OFFSITE_SOURCE_CHECKOUT, and each run entry its OFFSITE_PORT variables; the main
checkout’s agents and terminals keep their environment as it is.