Configuration
Where yeet keeps local client config, workspace registration, and replayable service state.
There are two kinds of local state. Client config answers "what host or workspace do I usually mean?" Project config answers "how do I replay this set of services?" Keep those jobs separate.
Yeet stores client config in:
$XDG_CONFIG_HOME/yeet/config.toml
If XDG_CONFIG_HOME is unset, yeet uses ~/.config/yeet/config.toml.
Existing ~/.yeet/prefs.json files migrate automatically on first run.
Schema:
default_host = "morpheus-catch"
workspaces = ["/srv/yeet-services"]
default_host is the catch host (Tailscale hostname) that yeet uses when
you do not specify a host with @<host>, --host, or yeet.toml. This is not
the SSH machine host from yeet init; it is the operating target after catch
is installed. See
Tailscale for details.
workspaces is the list of service workspace directories yeet can fall back to
when the current directory does not contain a yeet.toml. Each registered
workspace owns one or more catch hosts, and a catch host belongs to only one
registered workspace.
Commands:
yeet config
yeet config --host=<catch-host>
yeet config --workspace ~/yeet-services
yeet config --add-workspace ~/lab-services
yeet config --remove-workspace ~/lab-services
yeet config --clear-workspaces
--workspace and --add-workspace require the directory to already exist. To
create and register a workspace during host setup, use yeet init --workspace.
When you run yeet from a project directory, it can persist service defaults in
a yeet.toml file. This file is the replay recipe for the services in that
directory.
For homelab services, use a
Service Workspace so Compose files,
env files, Dockerfiles, scripts, binaries, and yeet.toml stay together.
yeet run --web writes the same project config entries as the matching CLI
path (yeet run or yeet cron). Payload paths, env files, service-root
settings, ZFS flags, snapshot overrides, cron schedules, and payload args are
saved in yeet.toml the same way.
Yeet first looks for yeet.toml in or above the current directory. If none is
found, it falls back to the registered workspace that owns the target catch
host. A local or upward yeet.toml always wins over workspace fallback.
If an interactive command finds a local yeet.toml that is not registered as a
workspace yet, yeet can ask whether to save that directory in client config. If
the file declares one catch host, yeet can also save that host as the default.
If it declares multiple hosts, yeet asks which one should become the default for
commands run outside the workspace.
Host ownership belongs in yeet.toml:
version = 1
hosts = ["morpheus-catch", "trinity-catch"]
Example:
version = 1
hosts = ["morpheus-catch", "trinity-catch"]
[[services]]
name = "uptime-kuma"
host = "morpheus-catch"
payload = "./uptime-kuma/compose.yml"
args = ["--net=svc,ts"]
[[services]]
name = "sensor-collector"
host = "trinity-catch"
payload = "./bin/sensor-collector"
args = ["--listen", ":9100"]
[[services]]
name = "backup"
host = "morpheus-catch"
type = "cron"
payload = "./jobs/backup.sh"
schedule = "0 3 * * *"
args = ["--target", "nas"]
Notes:
- Yeet stores
payloadrelative to theyeet.tomldirectory when possible. typeis optional; omit it (or setrun) foryeet run, and setcronforyeet cron.argsstores run flags followed by payload args, with the--separator removed. Yeet re-inserts--when needed to re-run the service. For cron, these are the binary args after--.scheduleis the 5-field cron expression fortype = "cron".hostscontrols host-scoped commands likeyeet statuswith no args.
If the live host state changes from another checkout, use yeet service sync
instead of editing around the drift by hand.
Client:
CATCH_HOST: default target catch host (Tailscale hostname). See Tailscale.
yeet edit uses $EDITOR if set, otherwise vim.