Raw ports
A way in that is not HTTP — ssh, DNS, WireGuard — carried to the app unread.
httpPort is what the proxy sends an app's hostnames to. An app may answer on ports beside it,
carried to it unread — tcp or udp, whatever arrives, the way a firewall rule would:
"config": {
"httpPort": 3000,
"ports": [
{ "name": "ssh", "guestPort": 22 },
{ "name": "dns", "guestPort": 53 }
]
}On the host
The host must name [proxy.raw] to bind such a port:
[proxy.raw]
listen_address = "10.0.5.18"
max_ports_per_guest = 2max_ports_per_guestis how many an app may name: 1 to 7, what a slot reserves past its HTTP port. A document that asks for more is refused by name, and the instance reportedfailed.listen_addressis a private address, where a relay reaches this host — never the world's. A raw port carries no hostname to route on, so it is reached at<listen_address>:<host port>rather than by name. The host port is the app'shostPortinreported.jsonplus the port's position inports, counted from one:sshabove ishostPort + 1,dnsishostPort + 2.
Good to know
A raw port is never published from this host: an address one app hands to its users would put every app on the host in front of them. The relay that publishes it is a machine of its own.
Waking
While the app sleeps, the first arrival wakes it, whichever way it came. A connection is accepted and held, then spliced once the guest answers, so a client sees a slow banner rather than a closed socket. A datagram is kept and delivered after the wake.