Containers
Deploy Compose files, Dockerfiles, image refs, and small source-file services.
Containers are the most common yeet payload. Catch installs them as Docker Compose services on the target host.
Use this path when the workload already has a container shape or when you want its runtime dependencies packaged with it. Containers reduce host drift. They do not eliminate networking, storage, or update decisions.
Run these commands from a
Service Workspace. The first
successful deploy writes yeet.toml in the current directory.
Yeet detects a YAML file with a top-level services: key as Docker Compose.
That file remains the center of the app's container model:
yeet run <svc> ./compose.yml
yeet run <svc> ./compose.yml --net=lan
Compose files should define their initial port mappings in the compose file.
After deployment, use yeet service set <svc> -p HOST:CONTAINER to replace the
yeet-managed published-port list for the primary service. The list is complete,
so include every mapping you want to keep.
yeet service set <svc> -p 80:80 -p 443:443
yeet service set <svc> --publish-reset -p 443:443
If the payload looks like an OCI image reference, catch pulls it on the host and yeet generates the Compose wrapper. This is the fastest path for public images and small tests.
yeet run <svc> nginx:latest
yeet run -p 8000:8000 <svc> ghcr.io/org/app:latest
For local images, push to yeet's host-side registry and run in one step:
yeet docker push <svc> <local-image>:<tag> --run
Dockerfile payloads are built locally for the host architecture, pushed to the catch host, then installed there. The build happens where you run yeet; the service runs where catch lives.
yeet run <svc> ./Dockerfile
yeet run -p 8000:8000 <svc> ./Dockerfile
Python and TypeScript source files are container-backed. Python runs through a
uv container image, and TypeScript runs through a Deno container. This is
useful for small services; it is not a substitute for understanding your app's
runtime needs.
yeet run -p 8000:8000 <svc> ./server.py
yeet run -p 8000:8000 <svc> ./server.ts
For Compose services, yeet run reuses existing images unless you ask for a
pull. Use --pull for a deploy-time refresh, or use the Docker commands to
inspect and update image state explicitly.
yeet run <svc> ./compose.yml
yeet run --pull <svc> ./compose.yml
yeet docker outdated
yeet docker pull <svc>
yeet docker update <svc...>
yeet docker update --outdated
For Dockerfile, image, Python, and TypeScript payloads, re-run yeet run with
the new payload or source file. If the service already exists in yeet.toml,
yeet reuses the saved run options unless you explicitly change the payload
configuration.
Container services can use ZFS-backed service roots for persistent data and yeet-managed snapshots before redeploys or Docker image updates. This is most useful for apps where the data directory matters more than the container image.
yeet run <svc> ./compose.yml --service-root=tank/apps/<svc> --zfs
yeet docker update <svc>
With --zfs, --service-root is a dataset name, not a filesystem path. Catch
accepts an existing dataset or creates it, then uses its mountpoint as the
service root. See ZFS for snapshot defaults, retention,
and service-root moves.
Use svc when the service needs private yeet traffic, yeet DNS, and outbound
internet through the catch host. Use svc,ts when the service also needs its
own Tailscale identity.
Use lan when the service should request a LAN or VLAN address and use that
network's DHCP gateway. Use lan,ts when the service needs both LAN presence
and a Tailscale identity.
yeet run <svc> ./compose.yml --net=svc
yeet run <svc> ./compose.yml --net=svc,ts --ts-tags=tag:app
yeet run <svc> ./compose.yml --net=lan
yeet run <svc> ./compose.yml --net=iso
Avoid plain --net=ts unless the service is tailnet-only or has a Tailscale
exit node. See Networking for mode details and
internet egress behavior.
See DNS for service discovery between svc services,
including short names and *.yeet.internal names.
Use iso when the image or application is untrusted and needs public IPv4
egress but must not initiate traffic to Catch, LAN, svc, Tailscale, or another
isolated project. Catch can still connect to every component on any port. Use
iso,ts only when the service also needs an explicit Tailscale identity.
ISO works with images, client-built Dockerfiles, Python, TypeScript, and an admitted Compose subset. It rejects published ports, host networking, elevated privileges and host namespaces, unsafe mounts or runtime sockets, custom DNS, extra networks, Catch-side Compose builds, replicas, and unknown service fields. The error names the rejected Compose field. Components in the same admitted project may communicate; other projects cannot. See Networking for the complete contract and limitations.
yeet info <svc>
yeet ip <svc>
yeet logs -f <svc>
yeet restart <svc>
yeet rm <svc>
Use yeet rm --clean <svc> when you also want to remove service data under the
managed service root and delete the local yeet.toml entry. Read the
confirmation prompt before accepting.
Docker hosts need Docker with Compose support. On Debian/Ubuntu-style hosts,
interactive yeet init asks before installing Docker and configures the Docker
settings needed for local image pushes.
See DNS for resolver behavior, Host Setup for host setup, and Workflows for common update flows. ZFS is optional; see ZFS if you want dataset-backed service roots.