Cloudflare Tunnel is a very useful way to publish a homelab service without opening inbound router ports. It is also easy to misunderstand.
The tunnel configuration is an allowlist of intended routes, not proof that every route is safe. For each hostname I want a record of the public name, the Docker origin, the container port, the purpose, and whether it should currently be reachable.
There are two separate checks:
- What does the tunnel configuration say should be exposed?
- What does an external request actually reach?
Both matter. A route can be configured incorrectly, point at the wrong container, or be publicly reachable when it was meant to be paused. Conversely, a deliberately disabled route may return a proxy error while its container remains healthy internally. That is an expected security control, not necessarily an application outage.
The tunnel connector should also be treated as sensitive infrastructure. It should have limited network visibility, a current image, protected credentials, and no unnecessary access to the Docker socket. Cloudflare Access, authentication, rate limits, and origin-level authorization remain valuable for administrative services.
The operational habit that helped most was testing after every route change: query the route from outside, check the local origin separately, and record the result. This prevents confusing a tunnel problem with an application problem.
The goal is simple: know exactly which services are public, why they are public, and how to make one unreachable without stopping unrelated services.
# Inspect the connector and its network visibility
docker ps --filter name=cloudflared --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}'
docker inspect cloudflared --format '{{json .NetworkSettings.Networks}}' | jq
# Check the configured tunnel
cloudflared tunnel list
cloudflared tunnel info <tunnel-name>
# Test actual external and internal reachability
curl -sS -o /dev/null -w '%{http_code}\n' https://service.example.test
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080
Replace placeholders and never paste tunnel tokens into notes or shell history.
Comments