A single public ingress can serve every machine on the LAN. On folk.zone the router forwards WAN :80/:443 only to the main server, and Caddy terminates TLS for every *.folk.zone vhost. Any HTTP service on any LAN machine can be served publicly by pointing a vhost at it: no extra router rules, no DNS changes, no new certificates.
*.folk.zone resolves to the WAN IP, so a new subdomain needs only a vhost.192.168.1.x:port over the local network. The upstream never leaves the house unencrypted, but it never needs to.1. **Run the app on the other machine.** It must listen on the LAN interface, not localhost: ''python3 -m http.server 8008 --directory ~/public'' binds ''0.0.0.0''. Give the machine a DHCP reservation so its IP never moves. If it runs a firewall: ''sudo ufw allow from 192.168.1.0/24 to any port 8008''. 2. **Add a vhost to the Caddyfile**, same shape as every other block:
files.folk.zone {
reverse_proxy 192.168.1.78:8008 {
header_up Host {host}
header_up X-Real-IP {remote}
header_up X-Forwarded-For {remote}
header_up X-Forwarded-Proto {scheme}
}
}
3. **Reload Caddy**: ''docker exec folkzone-caddy caddy reload --config /etc/caddy/Caddyfile''. If the file was replaced by rsync and reload sees no diff, restart the container. See [[folkzone:troubleshooting:caddy_autosave_not_loading_config|Caddy Autosave Not Loading Config]]. 4. **Verify**: ''curl -sI https://files.folk.zone | head -3''. First hit may take a second while the cert is issued.
0.0.0.0 or the LAN IP. An app on 127.0.0.1 is unreachable.
Caddy only speaks HTTP/S. For raw TCP/UDP, a router port-forward can point at any LAN IP: WAN:25565 → 192.168.1.78:25565 for a game server. That traffic bypasses the web stack entirely, which is fine for a dedicated service that is not a *.folk.zone site.