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.

1) Install yeet locally

Release install (recommended):

curl -fsSL https://yeetrun.com/install.sh | sh

Nightly build:

curl -fsSL https://yeetrun.com/install.sh | sh -s -- --nightly

2) Bootstrap catch on a host

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.

3) Sanity check

yeet version
yeet status

4) Deploy something

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.

5) Observe and iterate

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.