Announcing LocalNS

An auto-configuring nameserver for the services you run on your local network.

I mess around with a bunch of different projects in my spare time but it’s been a long time since I’ve thought one was worth tidying up into an actual release. Maybe it will be useful to you?

The problem I faced was that I had a whole bunch of services that I installed on my network, some in docker, some as standalone servers, some behind a Traefik proxy. In the docker case I was using macvlan networking so each service had its own IP address accessible to the entire network. Once I learned how to do all that it became trivial to spin up a new local service, say InfluxDB or Grafana with a couple of lines in a docker-compose file.

The challenge was remembering the IP address for each service. That is of course the job of a DNS server and while I played with various standard DNS server options it always involved more manual work than I wanted and I wanted features they weren’t really designed for like being able to override publicly published DNS names with internal IP addresses when on the local network.

Traefik’s method of auto-discovering services really inspired me. It will connect to the docker daemon and listen for containers starting and stopping and based on labels on the containers route requests to them. So I built something similar that I’m calling LocalNS. It connects to docker and for containers with a specific label it detects the IP address and answers queries for its name through DNS.

So I can trivially bring up a container with something like:

~$ docker run -d \ --network internal \ --label 'localns.hostname=grafana.mydomain' \ grafana/grafana
Code language: Shell Session (shell)

As soon as the container starts LocalNS detects it and starts responding to queries for the name grafana.mydomain with whatever IP address docker assigned it on the internal network.

Once I did that I realised I wanted the same for the services that Traefik was proxying. And Traefik has an API so LocalNS will also request the routing rules from Traefik and for the simple cases understand what hostnames Traefik will respond to and so expose those names over DNS.

There are a couple of other sources supported too and it shouldn’t be difficult to add more in the future. When asked for DNS names it doesn’t know LocalNS will forward the request to another DNS server.

It takes a small amount of configuration to set up LocalNS but once done it mostly configures itself as you change the services that are running elsewhere. I wouldn’t say the code is perfect right now but I’ve been using it as the nameserver for everything on my home network for two months now with no obvious issues.

You can check out the code at Github or there is documentation for how to actually use it.