Local development of a multi-tenant application (Image: @joaoscferrao)

Wildcard domains in local development

Jan Marsh
coodoo
Published in
2 min readJan 17, 2021

--

Developing a SAAS product with multiple tenants? Then you’re likely still editing your /etc/hosts or changing some variable in source-code to be able to view different tenants while developing your application on localhost. As we have done in the past.

Having something like tenant-a.yourdomain.loc point tolocalhoston your development machine makes developing and testing a multi-tenant application much easier. Simply by looking at the domain, it is clear for everyone that this is the local development environment of tenant A.
Until recently we would achieve this by editing our/etc/hosts files programmatically for each tenant like this:

127.0.0.1 pub.halbzeit.loc
127.0.0.1 vfb.halbzeit.loc
127.0.0.1 sport1.halbzeit.loc

Not cool and easy to get wrong! Why can’t we have wildcard domains in our/etc/hosts? Sadly this is not possible on any OS out of the box. So we went on a search…

Enterdnsmasq a lightweight, easy to configure DNS forwarder, designed to provide DNS to a small-scale network and never touch your Mac’s /etc/hosts file again 😌.

Requirements

Setup

Install dnsmasq via homebrew.

brew install dnsmasq

Then add the configuration file in /usr/local/etc/dnsmasq.conf.
address=/domain/127.0.0.1 is the important part here. It will send any host that contains halbzeit.loc to our webserver on localhost. So something.tenant.halbzeit.loc or tenant.halbzeit.locor evenhalbzeit.loc will all end up at 127.0.0.1. You can even do this with your real domain or just the any suffix. For example local.yourdomain.com or everything with suffix like .loc.

dnsmasq.conf (Don’t forget to REPLACE yourdomain.com)

Now start it!

sudo brew services start dnsmasq

Important: Each domain that we have configured in dnsmasq needs a corresponding entry in /etc/resolver/. So create the folder and append a file for each address. Example filename loc with contents nameserver 127.0.0.1 or via command-line:

sudo bash -c 'echo "nameserver 127.0.0.1" > /etc/resolver/halbzeit.loc'

Verify

Test that macOS has picked up the resolver:

scutil --dns

...
resolver #8
domain : halbzeit.loc
nameserver[0] : 127.0.0.1
flags : Request A records, Request AAAA records

Test that we haven’t broken anything and the new domains are reachable:

# Make sure we haven't broken our DNS
ping google.com
# Check that anything with halbzeit.loc works
ping halbzeit.loc
ping anything.tenant.halbzeit.loc

Finally open your Browser and try http://halbzeit.loc/.

Hint: Add a / at the end to not end up in google.

That’s it 🚀! You can now forget about /etc/hosts and start using wildcard domains in local development.

Note: You should avoid the *.devand*.loc,*.local domain suffix in local development. .dev exists as a real TLD and .local is used by the Bonjour Service on macOS. *.loc,*.lan work, but could be reserved one day just as it happened with *.dev. Use a real domain *.local.yourdomain.comor a suffix like .testto be safe.

--

--