For me, the decision to start self-hosting services and apps was gradual, beginning with an innate curiosity about what I could run. I'd be lying if I said it wasn't also partially morbid curiosity about what I could break, which all feeds into my personal risk profile. My big thing? I wanted to cut my reliance on the cloud so that things inside my network still run even when the internet is down.
That ties into a larger ethos of removing friction in my devices and services, which is why I've tried out so many remote access solutions. Tailscale is one of the easiest to start using, but the company doesn't officially support a fully self-hosted version (unlike NetBird and Pangolin). Instead, the open-source Headscale is a self-hostable version of Tailscale's control plane and provides a way to manage your tailnet.
I've been using it, and while it works, it comes with a new set of issues. I like that there's an option out there, and I will probably keep using it, but it's not for everyone.
What is Headscale and why wouldn't you want to use it?
Running your own infrastructure comes with headaches and compromises
Tailscale is powerful, secure, and easy to use, but it has one feature many in the self-hosting community have an issue with. The company hosts the control plane. If Tailscale changes its policies or goes bankrupt, or any other potential future problems crop up, the networking solution might go away. Enter Headscale, an open-source version of the control plane that provides ACL and management for your tailnet.
And that's where the limitations start. Headscale is designed for a narrow scope of a single tailnet. That's probably fine for most self-host or home lab enthusiasts, unless having multiple tailnets is part of your network segmentation. While it covers most of Tailscale's features, it doesn't support dynamic ACLs, Funnel, Serve, or network flow logs. That alone might be a dealbreaker if your home lab is set up to use Tailscale Funnel or Serve instead of relying on Cloudflare Tunnel.
The other big issue is that you need a dedicated IPv4+IPv6 from your ISP to use Headscale. CGNAT makes this almost impossible in many countries, and ruins the main reason I use Tailscale/Headscale, which is to get past firewalls securely. I don't want a static IP at home and while I could run Headscale on a cheap VPS, that puts my tailnet infrastructure on hardware I don't control, which is the whole point of using Headscale in the first place.
My earlier feelings about using the Headscale CLI for management have changed. Using CLI isn't a hardship if you're up to self-hosting the control plane. Plus, there are plenty of GUI replacements like Headplane, which makes Headscale look and feel like the Tailscale website. I can't get over the thought that my VPS might get popped or that I can't implement tailnet lock, but I appreciate that those aren't in everyone's threat model.
Plus, it breaks high-availability
Headscale also has an embedded DERP server, which manages NAT traversal and device connections between tailnet devices if direct connections aren't possible. That's handy, but Tailscale has the coordination server and DERP servers in different locations to ensure high-availability connectivity, because if a route to one goes down, the devices can use the other to coordinate connections. Self-hosting both on the same IP address could leave parts of your tailnet unreachable if something goes wrong with your server or VPS.
Mobile use is a little tricky
While Headscale supports the existing Tailscale clients available for mobile phones, Windows, macOS, Linux, and others, connecting to it instead of Tailscale's main servers is fiddly. Entering the non-default control plane URL (your Headscale instance) is hidden behind the debug menu, which is fine if you are the only person using your tailnet, but irritating enough if you have less technical family members that you're using the tailnet to share services with.
Headscale
Tailscale's real power is simplicity
It abstracts away the pain of secure remote access and wide-area mesh networking
While it's easy to describe Tailscale as a WireGuard-based VPN, it's also incredibly reductive. It's a software-defined networking platform that abstracts networking functions away from the hardware used to transport them. Think VLANs that aren't dependent on the network hardware to implement, and you're on the right track.
But it's more than that. Just as using Docker, LXC, or Kubernetes makes for more efficient servers by abstracting application code from the host they run on, Tailscale abstracts the control plane from the data plane, making for more efficient networking as the usual overhead is handled separately. Everything from access control to encryption to orchestrating peer-to-peer connections is dealt with by the control plane, enabling near-infinite scaling without changing any networking hardware.
This is done transparently to the user, who doesn't have to do anything more onerous than log in with their credentials. No more corporate VPN solutions breaking with every operating system update, or client update. No friction between installing the client and actually using the service. It just works, thanks to lots of clever software behind the scenes.
I've used Headscale, and I wouldn't recommend it to everyone
I like that Headscale allows me to continue using Tailscale on my personal devices if the main servers go dark. I'd have to re-add them all because there isn't a migration tool to pull an existing tailnet into Headscale (and there might never be), but that's okay with the number of devices and services I have connected. Even then, I'm using Tailscale's infrastructure because it's easier, so I'm not worrying about uptime, and for most users, I'd suggest they do the same.
