Publish a service
Map a hostname to a local service
Create an ingress mapping, confirm local reachability, and verify the complete Cloudflare-to-origin response path.
8 minute lesson
Run a small service on loopback first. Anything works — a Node app on port 3000, or:
python3 -m http.server 8080
Confirm it answers locally with curl http://localhost:8080 before involving the tunnel. Debugging two layers at once wastes time.
Add the ingress mapping
For a remotely managed tunnel, add the public hostname in the dashboard under the tunnel’s Public Hostnames tab. For a locally managed tunnel, the same intent lives in config.yml as ingress rules:
tunnel: 6ff42ae2-765d-4adf-8112-31c55c1551ef
credentials-file: /home/flavio/.cloudflared/6ff42ae2.json
ingress:
- hostname: app.flaviocopes.com
service: http://localhost:8080
- service: http_status:404
Rules match top to bottom, and the file must end with a catch-all rule that has no hostname filter. End the ingress rules with an explicit catch-all error so unmatched hostnames do not reach an accidental service. cloudflared refuses to start without one, which is a favor: it forces you to decide what unknown hostnames get, and http_status:404 is the safe answer.
Validate the file before running it:
cloudflared tunnel ingress validate
cloudflared tunnel ingress rule https://app.flaviocopes.com
The second command tells you which rule a URL would match. When a hostname hits the wrong service, this is how you find the ordering mistake.
Verify the whole path
Cloudflare handles edge TLS for the hostname, so https://app.flaviocopes.com works without you touching a certificate. But the tunnel protects transport to the connector, not the service itself. The local service and host still need patching, authorization, safe headers, and least privilege. Publishing does not harden anything.
Publish a harmless practice endpoint, test its headers and unknown paths, then stop cloudflared and confirm the failure is visible and expected. With the connector down, Cloudflare returns an error 1033 page with HTTP status 530 — that is what your users see during an outage, so look at it once on purpose. Restart cloudflared and confirm recovery needs no other action.
Lesson completed