LocalBinding

A device-local forward of a workstation's ports and Unix sockets to your machine.

A LocalBinding describes what this device forwards from a workstation: TCP ports and Unix sockets, statically or by auto-discovery. It is the single interface for device-local forwarding, and it is never routed or synced: each device owns and writes its own.

apiVersion: core.ringleader.dev/v1
kind: LocalBinding

Most of the time you don’t author one directly: a workstation’s spec.defaultLocalBinding template makes the daemon seed a LocalBinding once, when the workstation first reaches Running (deletion is honored: it won’t re-create one you remove). Author one explicitly when you want precise control.

Examples

Map a single port to a fixed host port, a one-line change. A per-port entry opts that port in on its own, so you don’t need forwardAll to forward just one:

spec:
  autoForward:
    ports: [{ port: 8080, localPort: 18080 }]   # workstation 8080 -> host 18080

Forward a workstation’s Docker socket to a fixed host path:

apiVersion: core.ringleader.dev/v1
kind: LocalBinding
metadata:
  name: docker
  namespace: dev
spec:
  enabled: true
  workstationSelector:
    matchName: my-box
  sockets:
    - remotePath: /var/run/docker.sock
      localPath: /tmp/ringleader-docker.sock

Auto-forward every listening port, with one exception and one override:

apiVersion: core.ringleader.dev/v1
kind: LocalBinding
metadata:
  name: runtime
  namespace: dev
spec:
  enabled: true
  workstationSelector:
    matchLabels:
      app: web
  autoForward:
    forwardAll: true
    ports:
      - port: 9999
        enabled: false        # exclude this discovered port
      - port: 80
        localPort: 8080       # override the host port
  urlForward:
    enabled: true
    open: false               # record opened URLs; don't auto-launch

Spec fields

FieldTypeDescription
enabledboolMaster on/off switch (default true). The CLI enable/disable flips this.
workstationSelector.matchNamestringTarget a single workstation by exact name.
workstationSelector.matchLabelsmapSelect potentially many workstations by labels.
autoForward.forwardAllboolForward every discovered listening port.
autoForward.portOffsetintBulk-shift the host port of every 1:1 auto-forward (workstation 8080 → host 18080 when 10000); 0/absent ⇒ 1:1. A per-port localPort override is absolute (not shifted).
autoForward.ports[][]objectPer-port overrides: {port, enabled, localPort} (localPort: 0 ⇒ ephemeral).
ports[][]objectStatic TCP forwards: {remotePort, localPort} (localPort: 0 ⇒ ephemeral).
sockets[][]objectStatic Unix-socket forwards: {remotePath, localPath}.
urlForward.enabledboolEnable the browser/URL bridge (workstation → host).
urlForward.openboolAlso launch each forwarded URL in the host browser (default: record only).

Provide exactly one of workstationSelector.matchName or matchLabels.

portOffset shifts only the 1:1 auto-forwards (a workstation port with no explicit localPort override); static ports[] and per-port localPort values are left absolute. If a shifted host port would fall outside the valid 165535 range, the offset is skipped for that one port (it forwards 1:1) rather than wrapping around, so a large offset never lands a high workstation port on 0 or a privileged low port.

Status fields

The daemon writes these per-device.

FieldTypeDescription
messagestringThe one human headline, e.g. 3 forwards active, 2 forwards active, 1 dropped, port forwarding is disabled for this binding, or no connected workstation matches matchName=web.
bindings[][]objectEndpoints actually forwarded right now: {kind, workstation, remotePort/localPort or remotePath/localPath, source, active}. source is static, auto, or seeded.
dropped[][]objectWanted forwards not forwarded, each with a human reason (e.g. host-port conflict).
conditions[][]objectA self-diagnosing Ready condition; reason is one of Disabled, Degraded, NotConnected, NoForwards, Pending.

status.message is derived from the same computation as the Ready condition, so the headline and the condition can never disagree. Read the condition’s own message for the per-aspect detail.

Conflict handling

When two bindings want the same host port, the daemon resolves it deterministically (first-wins by workstation [namespace, name], then binding [namespace, name]) and records the loser in status.dropped with a reason. It is never silent. Inspect the live picture with rl binding show.