dnsmasq

Many of us, back in the day, did web development, and to develop and test the next project locally we’d add another entry to /etc/hosts along the lines of:

127.0.0.1       next-project.tld

If the site supported subdomains — say, regional ones — /etc/hosts would balloon into a wall of text that you’d publish in the wiki to share with coworkers, updating it by hand every time a new subdomain showed up:

127.0.0.1       next-project.tld
127.0.0.1       msk.next-project.tld
127.0.0.1       spb.next-project.tld
...

These days, with us working with microservices most of the time, this problem partly belongs to the past: we spin up a service on its own port, surround it with mocks, and develop and debug.

But the need to fake environments hasn’t gone away. Local deployments may still need domains and subdomains for your services, for example:

svc1.minikube.dmz
svc2.minikube.dmz
svc3.minikube.dmz
...

Maintaining /etc/hosts is fairly inconvenient. New domains keep showing up; old ones go stale. On top of that, you’ll need to share its contents with your coworkers and keep that source of truth current.

To fully automate working with local domains and subdomains, I use dnsmasq. It’s a bit strange how rarely anyone brings it up — instead they keep maintaining /etc/hosts by hand.

Here’s a setup example on macOS. The Linux setup is similar; mind your distribution’s specifics. In the example we’ll set up the .dmz zone on the local machine:

brew install dnsmasq  # one of those rare cases
                      # where I recommend installing via brew

sudo mkdir -pv /etc/resolver
sudo bash -c 'echo "nameserver 127.0.0.1" > /etc/resolver/dmz'
echo 'address=/.dmz/127.0.0.1' >> $(brew --prefix)/etc/dnsmasq.conf

sudo brew services start dnsmasq

ping -c 2 project.dmz
ping -c 2 another.project.dmz

Now every domain in the .dmz zone is available on your machine without touching /etc/hosts. The whole thing works fairly transparently — you don’t need to change the DNS settings on your network adapter.

If you need more zones, add the corresponding config files following the same pattern, named after the zone you need.

A setup like this is easy to automate and reproduce on your coworkers’ machines, sparing the whole team from maintaining a constantly stale shared /etc/hosts source of truth.

What’s worth remembering? The .local and .dev zones actually exist and are reserved. The .dmz zone may be in use on your internal network. So before choosing a root zone for local use, check with your network-team coworkers. They’ll tell you which zone is safe to use for local development.