Configuring a fleet
fleet launch reads a single fleet-config.yaml and starts everything it
describes in one process: a bridge, any number of ships, and the web GUI. Ships
that the launch starts itself are registered with the bridge automatically.
This page covers the config format. For the individual fleet ship /
fleet bridge / fleet client serve flags, see the CLI
reference; for the exhaustive field table, see the config
reference.
Scaffold a config
Section titled “Scaffold a config”fleet launch initThat writes a commented ./fleet-config.yaml. It refuses to clobber an existing
file unless you pass --force, and --config-path <path> writes somewhere else.
Then bring the fleet up:
fleet launchfleet launch also takes --config-path <path>; it defaults to
./fleet-config.yaml. The process stays in the foreground — the bridge, ships,
and GUI are all servers listening in it.
The three sections
Section titled “The three sections”Every section is optional, and only the sections present are started:
bridge: dataDirectory: ./.fleet/bridge port: 4800 name: my-fleet-bridge
gui: port: 3000
ships: ship-a: fleetDirectory: ./fleet/ship-a port: 4700A section key with no body (bridge: on its own line) parses as “enabled with
defaults” rather than an error, so a minimal single-machine config is:
bridge:gui:ships: ship-a:bridge
Section titled “bridge”| Field | Default | Meaning |
|---|---|---|
dataDirectory |
./.fleet/bridge |
Where ships.json, repos.json and ephemeral.json are persisted. Resolved to an absolute path. |
port |
4800 |
HTTP + WebSocket port. |
name |
bridge |
Human-facing name of the bridge. |
The directory is created on startup if it doesn’t exist.
| Field | Default | Meaning |
|---|---|---|
port |
chosen by Bun | Port the GUI listens on. |
bridgeUrl |
the bridge started by this launch | Bridge origin the GUI reverse-proxies to. |
See Running the web GUI for what the GUI serves.
ships is a map, not a list. Each key names a ship, and the key supplies the
defaults for that entry:
ships: ship-a: source: local fleetDirectory: ./fleet/ship-a port: 4700 name: ship-a
ship-b: source: remote url: http://build-box:4700source defaults to local when omitted, so an entry with no source key is a
local ship.
Local ships (source: local) are started inside the fleet launch process:
| Field | Default |
|---|---|
fleetDirectory |
./fleet/<key>, resolved to an absolute path |
port |
4700 |
name |
the map key |
Remote ships (source: remote) are not started — they must already be
running somewhere. The only field is url, and it is required. The bridge
connects to that URL and discovers the ship’s real name from its first event
sync, so the map key is just a label in your config for a remote entry.
Validation rules
Section titled “Validation rules”fleet launch fails fast, before starting anything, on two cross-section
problems:
-
Two local ships on the same port. Every
source: localship needs its own port, since they all run in one process on one machine:ships "ship-a" and "ship-b" both use port 4700; give each local ship a distinct portRemote ships are exempt — they’re on other machines.
-
A GUI with nothing to proxy to. If you declare
guiwithout abridgesection, you must give it an explicitbridgeUrl:gui is configured with no bridge to proxy to; add a bridge section or gui.bridgeUrl
Ship registration failures are not fatal. If a ship can’t be reached or its
name collides with one already registered, fleet launch prints a warning and
keeps going:
could not register ship "ship-b" (http://build-box:4700): ship at http://build-box:4700 did not respond: timed out waiting for syncIf there is no bridge section at all, ships are still started, but nothing
registers them:
no bridge configured; not registering ship "ship-a" (http://localhost:4700)Worked example: one machine
Section titled “Worked example: one machine”Everything on a laptop — a bridge, one ship, and the GUI:
bridge: dataDirectory: ./.fleet/bridge port: 4800 name: laptop
gui: port: 3000
ships: local: fleetDirectory: ./fleet/local port: 4700fleet launchThe GUI is on http://localhost:3000, proxying to the bridge on 4800, which
drives the ship on 4700. Workspaces land under ./fleet/local/<repo>/<name>.
Worked example: a bridge fronting several ships
Section titled “Worked example: a bridge fronting several ships”Two ships on this machine plus two already running elsewhere:
bridge: dataDirectory: ./.fleet/bridge port: 4800 name: control
gui: port: 3000
ships: local-a: port: 4700 fleetDirectory: ./fleet/a
local-b: port: 4701 fleetDirectory: ./fleet/b
gpu-box: source: remote url: http://gpu-box.internal:4700
build-box: source: remote url: http://build-box.internal:4700The two local ships need distinct ports; the remote ones each need a URL the
bridge host can actually reach. See Running across several
machines for what happens when one of them is down, and
for the fleet-wide <repo>/<name> uniqueness rule.
What launch does not do
Section titled “What launch does not do”fleet launch registers ships with the bridge. It does not register repos — the
bridge’s repo registry is managed separately, and it persists in the bridge’s
dataDirectory across restarts. See Managing repos.