DevOps Toolbox · Youtube · 10:46

Stop Using Tailscale. Use Open Source Instead.

A 10-minute walkthrough that replaces Tailscale's closed coordination server with Headscale, the open-source drop-in that runs in your own cluster.

Posted
May 22nd 2026
6 days ago
Duration
10:46
Format
Tutorial
educational
Channel
DT
DevOps Toolbox
§ 01 · The Hook

The bait, then the rug-pull.

A viral tweet about Tailscale's SaaS dependency was all it took. The host had been happily running Tailscale for years — but once the framing landed, keeping a closed-source company's server in charge of his most sensitive internal traffic felt like an unnecessary bet. The switch to Headscale, the GitHub-popular open-source control server, took one video to document end to end.

§ · Chapters

Where the time goes.

00:00 – 00:44

01 · The SaaS problem with Tailscale

Hook via viral tweet. Tailscale praised but SaaS control plane called out. Promise: own your mesh network by the end.

00:44 – 01:08

02 · What you will have by the end

Explicit promise: your own mesh network accessible through a self-dug tunnel.

01:08 – 02:27

03 · WireGuard vs VPN vs mesh (theory)

Traditional VPNs route through a gateway, adding latency for geographically local access. WireGuard forms peer-to-peer mesh, not a gateway topology.

02:27 – 03:17

04 · Headscale config and k3s manifests

Walks configmap.yaml: server URL, listen addresses, metrics, private key path, IP prefixes. Caddyfile entry for public reverse proxy.

03:17 – 04:13

05 · Deployment and Headplane UI

Server container running, Headplane web UI installed, CLI alias created for executing commands inside the container.

04:13 – 05:35

06 · First node registered (MacBook)

headscale users create, tailscale up --login-server, URL exchange, node registered, mesh IP assigned.

05:35 – 06:30

07 · Sponsor: Internxt

Internxt cloud storage: RClone support, E2E encrypted, lifetime plan, 87% off via description link.

06:30 – 07:14

08 · Admin panel and node confirmed

Extract API key from container, log into Headplane, MacBook Pro node visible with internal IP.

07:14 – 08:31

09 · Subnet router: second node and k3s pod network

Deploy tailscale-subnet-router container, register as second node, approve subnets in Headplane to expose Kubernetes pod network.

08:31 – 09:29

10 · Live proof: Dozzle accessible, kill test

Grab k3s ClusterIP for Dozzle, access over Headscale tunnel. Tailscale down confirms isolation. Back up, back in.

09:29 – 10:46

11 · DNS pitfalls and the private-IP trick

AdGuard magic DNS breaks in browsers. Solution: public A record resolving to RFC-1918 private IP. Caveats, sidecar architecture suggestion, next-video CTA.

§ · Storyboard

Visual structure at a glance.

open
SaaS indictment
WireGuard theory
configmap
Headplane UI
node registered
Dozzle accessible
DNS resolution
CTA
§ · Frameworks

Named ideas worth stealing.

01:08 concept

Replace only the SaaS layer

Keep the best parts of a managed service (Tailscale client, WireGuard) and replace only the closed SaaS coordination layer with an open-source equivalent. No client-side changes required.

Steal for Any self-hosting argument: identify which layer is the SaaS dependency and replace just that layer.
09:50 concept

Public DNS resolves to private IP

Register a real public A record pointing at an RFC-1918 private address. Browsers trust it as a real public name, but the address is only reachable inside the mesh. No split-horizon DNS required.

Steal for Any home-lab internal service you want to name safely without running your own DNS resolver.
§ · Quotables

Lines you could clip.

00:12
"its brain is still SaaS — someone else's gateway."
On-screen text overlay, zero setup needed, lands the entire argument in one line. → TikTok hook
01:33
"Why would I travel across continents to have my laptop and phone securely access my security cameras?"
Concrete absurdity that makes the latency argument immediately tangible. → IG reel cold open
10:21
"setting up a single leg in the cluster and exposing everything is a bit of a new VPN problem."
Honest self-critique at the end; earns trust and teases the next video. → newsletter pull-quote
§ · Resources Mentioned

Things they pointed at.

00:00toolHeadscale ↗
04:13toolHeadplane (web UI for Headscale)
08:31toolDozzle (container log viewer)
§ · CTA Breakdown

How they asked for the click.

10:29 next-video
"to see the basics of this HomeLab cluster and how I made everything play together, check this video next"

Soft end-card CTA with honest self-critique immediately before it, which builds credibility.

§ 04 · The Script

Word for word.

HOOK opening / re-engagementCTA the pitch metaphor analogy
00:00HOOKHave you seen this tweet? It's not the only one, and it got me thinking. Tailscale is amazing.
00:05HOOKLike others, I've been happily using it forever, but its brain is still SaaS. So why don't I take control over it, especially when its open source counterpart is one of the most popular projects on GitHub? Beyond the fact that I'll be able to get unlimited users, unlimited policies from other resources, which are all capped unless you pay, I'll be the one controlling the gateway.
00:27HOOKNot a closed source server on a company I just blindly trust. When it comes to the most sensitive pieces I have, my internal home services, it feels even more sensible. Now I have nothing against Telescale on the contrary.
00:39HOOKA fantastic service built on top of the amazing WireGuard and given away for basically free, but it's not all about money. For me, it's about latency and control and a bit of nerd spice that forces me to self host and run services on my own just for fun.
00:54By the end of this one, you'll have the tools to run your own mesh network and access private services using a tunnel you dug yourself. Let's get into it.
01:08Headscale does exactly that, and it's directly aimed at replacing the Tailscale control center while you can keep enjoying their open source client. Now both of these are based on the same technology, WireGuard. And, sure, you can set up WireGuard yourself, but let's just say there's a good reason why people use Tailscale in the first place.
01:26WireGuard is hard. Tailscale makes it unbelievably easy. But why not a VPN, you may ask?
01:32Well, to put simply, this is a VPN. Clients use a gateway to get access to a bunch of servers.
01:37This can be incredibly inefficient if you're accessing a local machine while you're physically not far from it while your VPN server lives far, far away. And if you think that's a joke, think about companies running their sensitive infra like VPNs on AWS US East or West while having on prem infrastructure in their building, either across the country or on the other side of the globe.
02:00And that was my situation at home. Why would I travel across continents to have my laptop and phone securely access my security cameras? Well, WireGuard isn't forming a gateway, but rather a mesh network of nodes.
02:13You're a machine that joined the system. You're now part of the network infra running lightweight WireGuard tunnels between every available pair of nodes, making the system not only faster but also fault tolerant. For Tailscale, building on top of that, there's a main service,
02:27that's the server, helping coordinate, store private keys, etcetera. Enough theory.
02:31You can read more about it in the link below. Let's get this thing running. Now I've mentioned I have a home lab setup with k three s, so that's where it's going to live.
02:40You can set it up any way you like. It doesn't really change much. There are two important bits to the infra, the configuration and the server itself.
02:48Starting from the first, the server URL is actually not going to stay like that. I'm going to give it a real publicly available DNS, and we're solving the security risk here in a really cool way. Wait for the end for that.
03:00There's an address to listen on for connections and another one for metrics. This is pretty much all you need to get started. The head scale server is a container from their official Docker Hub release,
03:11and the command is simply head scale serve. Ports are configured to match the config we've shown earlier. An extra word about the configure.
03:19Head Headscale implements almost all Tailscale features. There's a long list right there. One of those features is Magic DNS, which basically gives you automatic internal DNS entries for different machines.
03:30And while this is cool, and I did configure it to play around, it's very problematic. DNS is simple but also complicated. If you play around with it like setting your own AadGuard or just use the magic DNS by head scale, you'll quickly realize not all devices are happy to route you to seemingly suspicious nonpublic entries.
03:49IPs work great, but who can work with these? There's a good reason DNS was ever created. So I've mentioned I'm using public records for mine, but in a way that keeps the service private.
04:00More on that later. As for caddy, which is the main HomeLab reverse proxy, we'll add a simple line that sends traffic from my public domain to the local case three s head scale service. So our server is up.
04:11Looks like it's running and listening, we can start working. Time to install the Telescale client.
04:17We mentioned this bit is open source and saves us the trouble of using anything different to create a node in the mesh network. Once it's ready, we'll probably want to add a small UI. And while Headscale doesn't come with one, there are plenty of options on GitHub.
04:32I went with head plane, the most popular option. Back to the server, head scale is actually its own CLI for different operations. And since it's running inside a container, I'll run a small trick to execute in it just to fire the command.
04:45And since I'm not gonna run this type of command every single time I want something, an alias can be helpful. Okay.
04:51Let's do this. Headscale users list comes up empty, of course. Users create with my name is pretty much enough at this point, and there I am.
05:01So you're setting up head scale as an alternative to tail scale which is great if you want more control over your own network. But once you start self hosting more of your infra, there's one thing you very quickly realize. Local is not the same thing as backed up.
05:15Your configs, keys, secrets, manifests, home lab notes, exported settings, all of these become part of the system. And if it only leaves on one machine or one NAS or one cluster, it's still a single point of failure. That's where Internxt fits in nicely.
05:30CTAInternxt is a privacy first cloud storage platform that works really well as an off-site backup target. It's open source, end to end encrypted with zero knowledge protection, GDPR compliant so much like the self hosted tools we talk about in this channel, the idea is that you stay in control of your data. Internets can store it, but they can't rid it.
05:48CTAFor DevOps workflows, the big thing is Rclone support. You can reconnect Internets drive natively or through webDAB, which means the same automation patterns you already use still apply.
05:59CTAScheduled backups, syncing config exports, pushing important files from remote machines or just keeping a copy of your home lab setup somewhere off-site. They've also added file versioning which is exactly the kind of thing you don't care about until the day you actually need it.
06:13CTAThe plan I think you should be focusing on right now is the lifetime ultimate plan. Five terabytes, one time payment, no monthly subscription. For an off-site backup target that's supposed to quietly exist in the background, that model makes a lot of sense.
06:26CTAUse the link in the description to check it out. The offer through that link gives you 87% off the lifetime ultimate plan, which is higher than what's currently available directly on the website.
06:36Now back to the video. Admin panel is ready, and it needs a key to start operating, extract it from the container using our alias, feed it to head plane, and there we go. No machines in the network just yet.
06:48My user is in place. Time to add the first node. Tailscale up with a custom login server, which accepts the routes and DNS entries as we've mentioned earlier for the Magic DNS.
06:59We get a URL to visit, which in turn generates a node registration command with a user and a key. Back to the server, register the node with our user, and boom. Node MacBook Pro two is registered.
07:12Headplane is also happy, and we've been given a special new IP of an internal new network formed right now with one device. Tailscale status from my machine and just a reminder, this is a node on the network, not the control server itself.
07:28It shows my machine as the only one in the mesh. Now here's my idea. I know I have my laptop as a single node, and my control plane is my home server.
07:39That's cool, but now I want to add what's known in the networking jargon as a leg in my home lab. Again, not the control server that isn't part of the game, but rather add another node. So I went ahead and deployed a very simple tail scale container.
07:52I called it subnet router with hopes it's one day going to literally allow some access to some devices, but I think that's pushing the envelope of what I'm doing here. Same process. This is a long line that gives Tailskill a command to register with the network using our domain.
08:07Okay. The node is trying to register. Now we need to visit the path in the control server.
08:13There's our command, and we're in. K three s router is ready. Over at head plane, I've added some subnets to make sure we can actually access Kubernetes internal pod network from remote.
08:25This is our way of exposing additional physical networks to Tailscale as well, and this requires approval, which is conveniently available here on the UI. Okay.
08:34Money time. I want to access Dozle, my log service, which is also an amazing open source, and I've covered it before in a video recently on the channel. For now, let's grab the internal k three s service and take our log view cluster internal IP that points at Dozzle.
08:51If we did everything right, I should be able to access this IP. Boom. Dozzle is up and accessible
08:56from outside the k three s cluster. All my application logs and monitoring is right there. Just to be extra certain, Tailscale down to kill the service and see if we can still access Dozzle.
09:07Nothing works. Fantastic. Tailscale back up and we're back in.
09:12Okay. Accessing Dozzle through the IP is going to be impossible. In comes DNS.
09:18Now one option I love is my local AdGuard, which is also, by the way, accessible now with ease through head scale where I can rewrite DNS entries like logs.domain and get there fairly quickly. There's a bit of a problem with Home DNS, which is why I'm reconsidering that setup.
09:34AdGuard is fantastic for blocking crappy ads, but when you add non standard fishy looking entries, browsers don't tend to trust or resolve these at all. And we're not even talking about HTTPS that adds another layer of annoyances if you want that. So I found something better.
09:50I went ahead and added another public IP, but one that resolves to a private address. If you have access, it works. But if you don't, and you shouldn't because it's inside my k three s cluster or at least I hope that's the case, you have nothing to do with it.
10:04Once that's propagated properly, my logs domain translates to Dozzle. Happy days. I gotta be honest here and say that first, DNS is way more trickier than this, and there are other options, especially for home labbers, which I'll explore on another video.
10:18CTABut regardless, I now have a direct link to my cluster applications. I do want to add, however, that setting up a single leg in the cluster and exposing everything is a bit of a new VPN problem. The better architecture would be to deploy a small Tailscale sidecar next to the applications I actually want exposed.
10:36CTALet me know if that's of interest in the comments. In the meantime, to see the basics of this HomeLab cluster and how I made everything play together, check this video next. Thank you for watching.
10:45CTAI'll see you on the next
— full transcript
§ 05 · For Joe

The one SaaS piece in your mesh network, and how to cut it.

WHAT TO LEARN

Tailscale's convenience is WireGuard with a coordination server on top, and Headscale replaces just the coordination server without touching a single client device.

  • Mesh networks route traffic directly between peers rather than through a central gateway, so a VPN that routes you through a distant server to reach a local machine imposes a latency penalty that grows with geographic distance.
  • Headscale is a fully open-source implementation of Tailscale's control server; all official Tailscale clients connect to it unchanged using the --login-server flag, so replacing the server requires no client-side changes.
  • Running the coordination server inside a cluster behind a public domain and Caddy reverse proxy is a practical deployment pattern — Caddy handles TLS automatically and the Headscale service never needs a public IP directly.
  • Browser-based internal DNS (AdGuard magic DNS, Headscale Magic DNS) tends to fail because modern browsers refuse to resolve non-standard entries that lack a recognizable public trust anchor.
  • Pointing a real public DNS A record at an RFC-1918 private address gives you a browser-trusted hostname for an internal service while remaining unreachable to anyone without mesh access.
  • A single subnet router that exposes an entire Kubernetes pod network recreates the original VPN blast-radius problem; per-application Tailscale sidecars give finer-grained access control with less exposure.
  • Self-hosting accumulates configuration state that exists only on the machines running it — manifests, private keys, and exported settings need off-site backup before they become load-bearing.
§ 06 · Frame Gallery

Visual moments.