# Managed by Ansible — do not edit manually. api.{{ domain }} { # MQTT auth is no longer an HTTP backend c2-core exposes (it moved to # mosquitto's own built-in dynamic-security plugin, administered over MQTT # control topics — see app/internal/dynsec.py) — there is currently no # /internal/* route in c2-core at all. This block stays anyway as defence # in depth: c2-core's app-wide reverse_proxy below forwards every path by # default, so this guarantees any FUTURE /internal/* route (or a # regression that reintroduces one) is still unreachable from the public # internet unless someone also deliberately deletes this block. `route` # forces top-to-bottom evaluation instead of Caddy's automatic directive # sorting, so this is guaranteed to run before reverse_proxy. route { respond /internal/* 404 reverse_proxy localhost:8888 { header_up X-Forwarded-For {remote_host} } } } # mqtt.{{ domain }} has no application behind it — mosquitto's TLS listener # (8883) is a raw MQTT socket, not HTTP, so Caddy can't reverse_proxy to it. # This block's only job is to make Caddy request+manage a Let's Encrypt cert # for the name via ACME HTTP-01, which infra/ansible's cert-sync unit then # copies out to mosquitto. The DNS A record for mqtt.{{ domain }} must exist # before this runs, or ACME issuance fails (see MQTT-PUBLIC-AUTH-PLAN.md). mqtt.{{ domain }} { respond 404 } # Frontend is served on the bare domain, not app.{{ domain }}: only drb and api # have public DNS records. A vhost for a name with no A record still starts, # but Caddy retries ACME against it forever and logs a failure each time. # To move it to app.{{ domain }}, create the A record first, then change this # line — the reverse_proxy target stays the same either way. {{ domain }} { reverse_proxy localhost:3000 { header_up X-Forwarded-For {remote_host} } }