// ITS FOSS — LINUX & OPEN SOURCE
I Got Tired of Remembering Ports for 30 Docker Apps in My Homelab. Here's How I Fixed it
My homelab runs on 5 machines with around 30 Docker containers. For a long time, the way I reached them was a bookmarks folder full of entries like http://100.101.12.4:8096.
Tailscale took care of getting me into my network from anywhere, but once I was in, I was back to remembering which box ran what on which port.
The usual fixes each have a catch. A reverse proxy with your own domain works, but it's one more thing to maintain, and every new app means touching two config files instead of one. Giving each container its own Tailscale sidecar gets you nice names, but it also turns the Machines page into a list of containers, each with its own auth key and state volume.
When Tailscale released Services, it looked like the thing I had actually wanted: names for apps, not for machines. I've been running my containers that way since, and this is a write-up of how it works, how to set it up by hand, and the two things worth knowing before you start.
A Service is a name plus a virtual IP on your tailnet, for example jellyfin.your-tailnet.ts.net. It doesn't belong to a device. Instead, one or more of your machines advertise it, and Tailscale routes clients to them.
So your Docker host stays a single machine in the tailnet, and the apps on it become Services. Access rules can point at a Service directly, so you can let someone reach Jellyfin without giving them the whole host.
Here is what a request looks like once it's set up:
Two details in that picture matter later: tailscaled on the host terminates HTTPS and talks plain HTTP to your app, and it adds an X-Forwarded-For header. To your app, Tailscale behaves like a reverse proxy.
Before automating anything, it's worth doing it manually once for a single container. You need three things.
1. A tagged host. Services are advertised by tagged machines, so give your Docker host a tag: