Quick Start
Fastest path to a working yeet + catch install.
This is the TL;DR path to a working install. It assumes you have a Linux host with systemd and SSH access. You do not need Tailscale installed on either machine; yeet uses an embedded tsnet client for RPC. See Tailscale for details.
Release install (recommended):
curl -fsSL https://yeetrun.com/install.sh | sh
Nightly build:
curl -fsSL https://yeetrun.com/install.sh | sh -s -- --nightly
Use SSH to install the catch service on a remote host:
yeet init root@<host>
If you use a non-root user, yeet will invoke sudo on the remote. Add --nightly
for nightly.
Note: this <host> is the machine host you SSH into. After install,
yeet run <svc>@<host> uses the catch host (Tailscale/tsnet hostname). See
Tailscale.
yeet version
yeet status
Docker Compose (most common):
yeet run <svc> ./compose.yml --net=lan
To place a new service under a custom root on the catch host, pass an absolute
host path or, with --zfs, a dataset name:
yeet run vaultwarden ./compose.yml --service-root=/srv/apps/vaultwarden
yeet run vaultwarden ./compose.yml --service-root=tank/apps/vaultwarden --zfs
For ZFS-backed service roots, pass --zfs and use the dataset name as
--service-root; catch resolves the dataset mountpoint and stores both the
dataset identity and the resolved filesystem path.
If the dataset does not exist, catch runs plain zfs create <dataset>. Parent
datasets must already exist. If the dataset already exists or its mountpoint
already contains files, catch prints a warning and deploys into it.
ZFS-backed services also get yeet-managed snapshots before redeploys, Docker image updates, and ZFS-backed service-root migrations. The default policy is enabled, required, keeps 5 snapshots, and prunes snapshots older than 7 days.
Find the service IP on your LAN:
yeet info <svc>
yeet ip <svc>
Dockerfile (built locally for the host’s arch, then pushed):
yeet run <svc> ./Dockerfile
Binary:
yeet run <svc> ./bin/<svc>
Docker image (pulled on the host):
yeet run <svc> nginx:latest
Local image (push it, then run it):
yeet docker push <svc> <local-image>:<tag> --run
Experimental VM on a KVM-capable Linux host:
yeet run <svc> vm://ubuntu/26.04 --net=svc
yeet vm images
yeet vm images update
yeet ssh <svc>
yeet vm console <svc>
yeet ssh <svc> opens the interactive guest shell. yeet vm console <svc>
streams serial output for boot diagnostics. Use yeet rm --clean-data <svc> to
delete the guest disk when removing a VM.
VM image bundles are cached per host. yeet vm images shows cache state, and
yeet vm images update refreshes the image used for future VM creates without
rewriting existing VM disks. A missing image is downloaded automatically on the
first VM create.
yeet logs -f <svc>
yeet restart <svc>
If you change the binary or compose file, re-run the same yeet run command to
roll a new generation. For an existing service, a payload-only redeploy reuses
the saved run options from yeet.toml and changes only the payload. For compose
images, add --pull (or use
yeet docker update <svc...>) when you want to refresh selected services. Use
yeet docker outdated to check for image updates and
yeet docker update --outdated to update only compose services with available
image updates.