Publishing a Next.js app through a Cloudflare Tunnel
Serving a self-hosted app on a real domain without opening a single inbound port — and the resolver quirk that made it look broken when it was not.
هذه الأدلّة محفوظة بالإنجليزية. فالأوامر وملفّات الإعداد واحدة في كلّ اللغات، وتوزيعها على ثلاث نسخ لا يضيف إلّا احتمال تخلّف إحداها عن التحديث.
العناوين في هذا الدليل عناوين بديلة ضمن النطاق 10.0.0.0/24 والنطاق المستخدم هو example.dev. وما عدا ذلك منقول حرفياً عن الملاحظات الأصلية.
- 01
Install and authenticate
The tunnel dials out to Cloudflare and traffic returns down that connection, so the origin needs no port forwarding and no public address at all.
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb sudo dpkg -i cloudflared-linux-amd64.deb cloudflared login - 02
Create the tunnel and point it at the app
cloudflared tunnel create nextjs-tunnel/etc/cloudflared/config.yml tunnel: nextjs-tunnel credentials-file: /home/master/.cloudflared/<tunnel-id>.json ingress: - hostname: example.dev service: http://10.0.0.80:30000 - service: http_status:404 - 03
Route DNS and run it as a service
Delete any existing A/AAAA/CNAME record for the hostname first; the route command creates the CNAME it needs and will not overwrite a conflicting record.
cloudflared tunnel route dns nextjs-tunnel example.dev sudo cloudflared service install sudo systemctl restart cloudflared - 04
The resolver fix
On the origin host the tunnel hostname resolved to a local IPv6 address, so requests from the machine itself never left the box — while every external client worked fine. Pinning the resolver fixed it.
/etc/systemd/resolved.conf [Resolve] DNS=1.1.1.1 FallbackDNS=8.8.8.8sudo systemctl restart systemd-resolved curl -v https://example.dev