The Free Encyclopedia

Tailscale Serve on 443 While Apache Stays on 80

Revision as of Jun 25, 2026 22:56 by albert.

On your-app-host, Tailscale Serve owns port 443 and Apache stays on port 80 only. This split gives the site private HTTPS over the tailnet (Tailscale provisions the cert) while Apache stays a simple plain-HTTP origin.

The hard rule

Never let Apache bind to 443 on this host. Enabling mod_ssl / an SSL vhost makes Apache grab 443, which collides with Tailscale Serve and breaks the site. Keep Apache on *:80 exclusively.

If you see the site break after an Apache change, check that nothing started listening on 443:

sudo ss -ltnp | grep ':443'        # should be tailscaled, NOT apache2
sudo apachectl -S | grep 443       # should print nothing

How the split works

client ──HTTPS:443──> Tailscale Serve ──HTTP──> Apache :80 (vhost) ──> app
         (TLS here)                    (plain, localhost)

Tailscale Serve terminates TLS and reverse-proxies to the local Apache:

# serve local Apache (port 80) over HTTPS on the tailnet
tailscale serve --bg 80
tailscale serve status

Why this layout

  • No cert management in Apache — Tailscale issues and renews the cert.
  • Private by default — only tailnet members reach :443; good for internal/admin surfaces.
  • Simpler origin — Apache config is just name-based vhosts on :80 (see Apache Name-Based Virtual Hosts on One Server).

Contrast with the public sites

Public thelabsource.com hosts take the opposite-but-compatible approach: Cloudflare terminates TLS and a tunnel reaches Apache on :80. Either way the principle holds — something else owns 443, Apache owns 80.

Access note: your-app-host is reached via an your-jump-host SSH jump host.