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.

Client config

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.

Project config (yeet.toml)

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 payload relative to the yeet.toml directory when possible.
  • type is optional; omit it (or set run) for yeet run, and set cron for yeet cron.
  • args stores 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 --.
  • schedule is the 5-field cron expression for type = "cron".
  • hosts controls host-scoped commands like yeet status with no args.

If the live host state changes from another checkout, use yeet service sync instead of editing around the drift by hand.

Environment variables

Client:

  • CATCH_HOST: default target catch host (Tailscale hostname). See Tailscale.

Editor

yeet edit uses $EDITOR if set, otherwise vim.