Skip to content

Daemon & service ​

connect and ssh work fine on their own, but each invocation dials a relay and completes the handshake from scratch. The daemon removes that cost: it is a long-running process that holds a warm carrier pool to each configured relay — with idle standbys for isolated services, automatic re-bridging on carrier death or network change (see Connect & SSH), and liveness keepalive — so sessions that go through it start instantly, and the relays/gateways commands have something to talk to. The daemon is unix-only (macOS and Linux).

Running it in the foreground ​

sh
burrowee daemon

It loads ~/.burrowee/cli/config.json, opens a carrier per relay, and serves requests over a local unix socket, printing a status line like:

burrowee daemon: socket=/home/you/.burrowee/cli/sockets/transport.sock gateways=1 relays=2 edges=2

It runs until interrupted (Ctrl-C). Two flags if you need them:

FlagMeaning
--config <path>config.json path (default ~/.burrowee/cli/config.json)
--socket <path>transport IPC socket path (see below)

Foreground mode is fine for trying things out or running under your own supervisor (tmux, a custom systemd unit). For day-to-day use, install the managed service instead.

The managed service ​

sh
burrowee service install

This writes and loads the system unit for the binary you ran it with (it elevates via sudo for the write): on macOS a launchd daemon at /Library/LaunchDaemons/com.burrowee.cli.plist, on Linux a systemd unit at /etc/systemd/system/burrowee-cli.service. The unit simply runs <your binary> daemon — as you, the installing user, not as root — starts it at boot with no GUI login required, and restarts it whenever it exits. Running at the system level is what keeps the daemon alive on a headless Linux box: the older per-user (systemctl --user) units died with the SSH session that started them.

There is one system slot per machine. If the installed unit belongs to a different user, service install refuses to take it over unless you consent explicitly with --force-service-override (or BURROWEE_FORCE_SERVICE_OVERRIDE=1 in the environment). Legacy per-user units from older releases (the org.burrowee.cli launchd agent, the systemd --user unit) are migrated away when you install the system unit, though service status still probes for them.

You rarely need to re-run install by hand after the first time: burrowee update restarts the managed service automatically whenever the installed version actually changed, and burrowee reinstall re-renders the unit itself.

Check on it:

sh
burrowee service status

This asks launchd/systemd for the system unit's state (probing the legacy per-user units too) and prints the supervisor's own dump, with a friendly not loaded / not active line when the unit isn't running.

Restart it:

sh
burrowee restart

restart bounces the managed system service. The CLI never elevates itself — the daemon runs as you — so if the supervisor demands privileges, you're offered the exact command to run rather than a silent sudo. On a platform with no managed unit model, or when you run the daemon under your own supervisor (tmux, a custom unit), restart refuses and tells you to restart burrowee daemon yourself.

burrowee status and burrowee doctor ​

sh
burrowee status                    # read-only, always exits 0
burrowee doctor [--fix] [--yes]    # the same report; --fix applies thin remediations

status and doctor print the same merged report: a version header, then health rows — whether you're paired, whether the relay your default gateway dials is reachable (a plain TCP dial, 3s budget), whether the daemon is running (a probe of the transport socket) — then an operational snapshot from the running daemon (your default gateway and its relay count, per-relay liveness), and finally the versions block. Each health row is marked ok/✗.

Both are read-only and always exit 0 on a supported platform: an unreachable daemon renders as a ✗ health row, not a failure exit, so a script should read the report rather than the exit code. (status on a non-unix platform keeps its "unix only" exit 2, but still prints the versions block.)

doctor --fix is the difference: it applies the thin remediations doctor knows about — first and foremost starting a down daemon via the managed service, after a confirmation prompt (--yes skips it, for scripting). It never elevates. A down daemon is repaired before the unpaired check, so a fresh machine gets its daemon up and is then pointed at burrowee bootstrap. --config <path> overrides the config.json location, same as elsewhere.

burrowee stats ​

sh
burrowee stats [--json]

A snapshot of the daemon's carrier pool: per-carrier stream counts and byte totals, straight from the running daemon over its socket. --json emits the raw daemon payload for scripts; --socket <path> points at a moved socket, same as below.

The socket ​

The daemon listens on a unix socket at ~/.burrowee/cli/sockets/transport.sock. On a pathologically long home path it falls back to $XDG_RUNTIME_DIR/burrowee/transport.sock (the OS temp directory when XDG_RUNTIME_DIR is unset). relays use/rm/gateway default/pair/probe/reset, stats, and the equivalent gateways mutators talk to the daemon over this socket (relays list and gateways list read config.json directly and need no daemon); if you moved it with --socket, pass the same --socket to those commands. uninstall removes the socket as part of cleanup.