The two doors a website needs
A web server listens on numbered ports — think of them as doors into your machine, each one agreed in advance so browsers know where to knock. Hosting a homepage needs exactly two:
- Port 80 — HTTP. The original, unencrypted web port. Almost nobody serves real content here any more, but you still need it open: it's where browsers land when someone types your address without https://, and it's how Let's Encrypt verifies you control the domain before issuing a certificate.
- Port 443 — HTTPS. The encrypted one, and where your site actually lives. This is what the padlock means. Block this and you have no working website, however well the rest is configured.
Caddy uses both: it takes the certificate challenge on 80, redirects visitors from 80 to 443 automatically, and serves everything encrypted on 443. That's why step 03 has you forward both, not just the one you think of as "the web".
What they actually do to you
Before reaching for a fix, work out which problem you have — they need different answers.
- Blocked inbound ports. Many residential ISPs drop traffic to ports 80 and 443 — precisely the two you need. Nothing you host is reachable, and Let's Encrypt's certificate check fails because it can't reach port 80.
- CGNAT (Carrier-Grade NAT). You share one public address with hundreds of other customers. There is no port to forward — inbound connections are impossible by design. Common on mobile and newer fibre.
- Dynamic addresses. Your IP changes without warning, so any DNS record pointing at it goes stale.
- Terms-of-service clauses. Plenty of consumer contracts forbid "running servers" outright, regardless of what's technically possible.
- Asymmetric bandwidth. 500 Mbps down and 20 up is normal. Serving is upload-bound, and upload is what they sold you least of.
Tailscale: stop asking permission
Tailscale builds an encrypted private network between your own devices. Each machine gets a stable address that works from anywhere, and connections are established outbound — so blocked inbound ports, CGNAT, and dynamic addresses all simply stop mattering. Nothing is exposed to the public internet, and there is no port to forward.
It's free for personal use, and built on WireGuard, which is open source. The coordination service is proprietary; if that bothers you, Headscale is a self-hosted replacement for it.
Install it on the box
root@box:~$ sudo tailscale up
# prints a login URL — open it, sign in, done
The installer detects your distribution and adds the right repository, so updates arrive through apt like everything else.
you@mac:~$ sudo tailscaled install-system-daemon
you@mac:~$ sudo tailscale up
There's also a Mac App Store version with a menu-bar UI, which is easier if this Mac is your everyday machine rather than a server.
Tailscale has a proper native Windows client — this is one of the few places you don't need WSL2. Install it on the Windows host itself:
# then sign in via the system-tray icon
If your server is running inside WSL2, install Tailscale on the Windows host rather than inside WSL — the host handles the networking for both.
Add your other devices
Install Tailscale on your laptop and phone from tailscale.com/download and sign in with the same account. They appear on the same private network automatically. From then on your server is reachable at a stable name — http://arbiter — whether you're at home, at work, or on mobile data.
Serve your site over real HTTPS
This is where it beats port-forwarding outright. Tailscale issues genuine, publicly-trusted certificates for a *.ts.net hostname — no browser warnings, no domain purchase, and the machine stays unreachable from the open internet.
Point it at whatever is already serving locally — Caddy on port 80 from step 03, or a test server on 8000. The certificate is fetched and renewed automatically.
When you want it genuinely public
Everything above keeps the site private to your devices. To publish it to the world despite a hostile ISP, you have a few options:
- Cloudflare Tunnel — a daemon on your box holds an outbound connection to Cloudflare, which serves your domain publicly. Free, works behind CGNAT, and lets you use your own domain name.
- A cheap VPS as a front door — $5/month buys a machine with a real static IP and unblocked ports. Run Caddy there as a reverse proxy back to your home box over Tailscale. Full control, your domain, no ISP involvement.
- A business line — if self-hosting becomes central to what you do, a business plan with a static IP and no server clause is the honest fix.
What about the DNS problem?
If you do have unblocked ports but a changing address, you don't need any of the above — just a dynamic DNS client that updates your record when the IP moves. Providers like No-IP and DuckDNS are free, and Caddy will then fetch certificates normally.
Before you move on
- You know which problem you actually have (blocked ports, CGNAT, or dynamic IP)
- Tailscale installed on the box and at least one other device
- tailscale status lists both machines
- Your site loads over HTTPS on the ts.net name
- If publishing publicly: Funnel, a tunnel, or a VPS front door chosen
With the network problem solved, the next rung is the one that depends on it most — mail.