Networking
Choose who can reach a service, what it can resolve, and how it gets out.
Network mode choice decides who can reach the workload, what names it can resolve, and where ordinary outbound internet goes.
Choose the inbound path and the outbound path together. A service that can be reached still needs to resolve names, download updates, and call APIs.
| Need | Use | Internet egress |
|---|---|---|
| Publish one container port on the catch host | -p HOST:CONTAINER | The workload's current network path |
| Private yeet service traffic and yeet DNS | --net=svc | Catch host gateway |
| Tailnet identity plus normal service networking | --net=svc,ts | Catch host gateway |
| LAN or VLAN address | --net=lan | DHCP gateway from the LAN or VLAN |
| LAN or VLAN address plus tailnet identity | --net=lan,ts | DHCP gateway from the LAN or VLAN |
| Tailnet-only service | --net=ts | No ordinary internet unless you configure an exit node |
| VM LAN access plus yeet-managed fallback | --net=svc,lan | LAN gateway for normal traffic |
For most services that need a Tailscale identity, start with svc,ts, not
plain ts. svc,ts keeps yeet DNS, private service traffic, and internet
egress through the catch host while adding a tailnet identity. Plain ts is
for services that are intentionally tailnet-only or have an exit-node plan.
Modes are comma-separated:
yeet run <svc> ./compose.yml --net=svc,ts --ts-tags=tag:app
VMs support svc, lan, and svc,lan. VM networking does not support ts as
a yeet VM network mode.
Use published ports when the workload only needs a TCP port on the catch host:
yeet run -p 8080:80 <svc> nginx:alpine
-p is not a network mode. It exposes a host port for image, Dockerfile,
Python, and TypeScript payloads. Use --net only when the workload also needs
private service networking, LAN presence, or a Tailscale identity. More network
modes make the service reachable in more ways, which is not automatically a win.
Change ports later with service set. The port list is complete, so include
every mapping you want to keep:
yeet service set vaultwarden -p 80:80 -p 443:443
Replace or clear the list intentionally with --publish-reset:
yeet service set vaultwarden --publish-reset -p 443:443
yeet service set vaultwarden --publish-reset
Check the live ports first:
yeet info vaultwarden
svc gives a service or VM a private yeet-managed address.
Use svc when the workload needs:
- Private service-to-service traffic.
- Yeet DNS names, such as
vaultwardenandvaultwarden.yeet.internal. - Ordinary outbound internet through the catch host's gateway.
- A stable VM management path through catch.
yeet run <svc> ./compose.yml --net=svc
yeet ip <svc>
Services and VMs on svc can resolve each other by short name and
*.yeet.internal names:
http://home-assistant:8123
postgres://postgres:5432/app
Use svc as the default private app network. Add ts when the service also
needs a tailnet identity. Add lan when the service or VM also needs a LAN
address.
The svc network currently requires exclusive use of 192.168.100.0/24 on the
catch host. If that range overlaps an existing host route, catch rejects new
svc networking.
See DNS for resolver behavior.
lan attaches a workload to the catch host's LAN. Containers and other
non-VM services use macvlan. VMs attach their guest TAP device to a host bridge.
In both cases, the workload requests addressing through DHCP.
Use lan when the workload should behave like a normal device on the LAN or
VLAN:
yeet run <svc> ./compose.yml --net=lan
yeet ip <svc>
With lan, ordinary outbound internet uses the gateway and DNS from that LAN
or VLAN. If the LAN has no gateway, blocks outbound access, or hands out the
wrong DNS, the workload inherits that behavior.
Use lan,ts when LAN clients and tailnet clients both need to reach the same
service:
yeet run <svc> ./compose.yml --net=lan,ts --ts-tags=tag:app
Override the parent interface or VLAN when needed:
yeet run <svc> ./compose.yml --net=lan --macvlan-parent=<iface>
yeet run <svc> ./compose.yml --net=lan --macvlan-parent=<iface> --macvlan-vlan=<id>
Use lan only on networks where macvlan, DHCP, and the selected parent
interface make sense. A WAN-only VPS usually should not use lan. If there is
no meaningful LAN, use svc or ts instead.
For VM lan networking, yeet needs a bridge on the host LAN. If the host
already has one on the default route, yeet uses it. On supported Debian/Ubuntu
hosts without a bridge, interactive yeet init or the first yeet run <vm> ... --net=lan can prepare br0 after confirmation. Bridge preparation can briefly
interrupt host networking; if your command disconnects during the change, rerun
it after the host comes back.
ts gives a service its own Tailscale identity, tailnet IP, tags, ACLs, and
Tailscale Serve support.
Use svc,ts for most services that need Tailscale:
yeet run <svc> ./compose.yml --net=svc,ts --ts-tags=tag:app
yeet ip <svc>
This keeps yeet DNS and ordinary outbound internet through the catch host while adding a tailnet identity.
Use plain ts only when the service is intentionally tailnet-only:
yeet run <svc> ./compose.yml --net=ts --ts-tags=tag:app
Plain ts does not provide ordinary outbound internet by itself. Configure a
Tailscale exit node when a ts-only service needs internet access:
yeet run <svc> ./compose.yml --net=ts --ts-tags=tag:app --ts-exit=<exit-node>
For an existing Tailscale service, run Tailscale commands inside that service identity:
yeet tailscale <svc> -- set --exit-node=<exit-node>
Make sure the OAuth client saved during catch setup can assign every tag you
pass with --ts-tags.
See Tailscale for OAuth setup, tags, exit nodes,
and yeet tailscale commands.
| Mode | Use when | Avoid when |
|---|---|---|
svc | The workload needs private yeet traffic, yeet DNS, or catch-host internet egress. | LAN clients need a LAN IP or tailnet clients need a service identity. |
lan | The workload should be a LAN or VLAN device. | The host network cannot provide DHCP, routing, or macvlan support. |
ts | The workload is deliberately tailnet-only, or an exit node handles internet egress. | The workload needs normal internet, yeet DNS, or private service traffic. |
svc,ts | The workload needs private yeet networking plus a tailnet identity. | The workload must appear as a LAN device. |
lan,ts | The LAN handles ordinary egress and the service also needs a tailnet identity. | The workload needs yeet DNS or private service traffic. |
svc,lan | A VM or service needs LAN presence plus yeet private networking. | The workload does not need the LAN. |
svc,lan,ts | A non-VM service truly needs private yeet traffic, LAN presence, and tailnet identity. | A simpler mode covers the real access path. |
For VMs, svc is the default. svc,lan gives the VM LAN access and keeps a
catch-managed fallback path. A LAN-only VM must be reachable from your
workstation on its guest LAN IP for yeet ssh <vm> to connect directly. If no
host LAN bridge is ready yet, yeet asks to prepare one before creating the VM.
Bridge preparation can briefly interrupt host networking.
yeet run <vm> vm://ubuntu/26.04 --net=svc,lan
yeet ssh <vm>
Force the proxy path:
yeet ssh --force-proxy <vm>
Inspect the current addresses and saved network model:
yeet info <svc>
yeet ip <svc>
Use the output to confirm:
svcshows a private service-network address.lanshows a LAN or VLAN address from DHCP.tsshows a tailnet address and Tailscale state.
If the service has no outbound internet, debug by network mode:
- Use
svcorsvc,tswhen the catch host should provide egress. - Check the LAN gateway and DNS when the service uses
lan. - Configure a Tailscale exit node when the service uses plain
ts.
mount and umount manage host-level network mounts:
yeet mount host:/export data-share --type=nfs --opts=defaults
yeet umount data-share
Mounts are host-level resources, not per-service network modes.
- Tailscale covers catch host access, per-service Tailscale identities, tags, and exit nodes.
- DNS covers names inside
svc. - VMs covers VM networking and SSH behavior.
- Troubleshooting covers common network failures.