If you ever needed to create a system so that you could create user-specific dynamic subdomains like username.myapp.com
, you will have run into that problem that getting this kind of thing working locally is tough.
Sure, you can edit your hosts file but it doesn't allow for wildcard subdomains (e.g. *.myapp.com
), so it's only a viable solution if your address is static (e.g. api.myapp.com
).
Here is how you can get wildcard subdomains running on your local system in 5 minutes:
1. Install Dnsmasq
Dnsmasq is a local DNS server. That means it tells your OS which IP address to go to for a given domain name. We will use this to point any *.test-domain to our local machine, localhost
.
Terminal
$ brew install dnsmasq
2. Configure Dnsmasq to route *.test-domains to localhost
First, figure out where the Dnsmasq config file lives:
Terminal
$ brew --prefix/usr/local
So in my case, it will be in /usr/local/etc/dnsmasq.conf
.
/usr/local/etc/dnsmasq.conf
# Route all *.test addresses to localhostaddress=/test/127.0.0.1# Don't read /etc/resolv.conf or any other configuration files.no-resolv# Never forward plain names (without a dot or domain part)domain-needed# Never forward addresses in the non-routed address spaces.bogus-priv
3. Run Dnsmasq now and anytime we restart the system
Terminal
$ sudo brew services start dnsmasq
Note: The sudo here is important!
4. Make macOS use our local DNS server (Dnsmasq) for *.test-addresses
Create the following file at /etc/resolver/test
:
/etc/resolver/test
nameserver 127.0.0.1
With that, you can go to subdomain.test
in your browser and it will point to localhost
. So if your app is running on port 3000
, simply go to subdomain.test:3000
.
But what if you're looking for the following setup?
myapp.test -> localhost:8000api.myapp.test -> localhost:3000*.api.myapp.test -> localhost:3000
This we can solve with Caddy which is a super-awesome simple HTTP server!
5. Install Caddy
Terminal
$ brew install caddy
6. Configure Caddy
In my case (because my brew --prefix
is /usr/local
), my global Caddyfile is at /usr/local/etc/Caddyfile
. This file we can setup to act as a simple reverse proxy for our individual apps running on different ports:
/usr/local/etc/Caddyfile
http://myapp.test {proxy / localhost:8000}http://api.myapp.test, http://*.api.myapp.test {proxy / localhost:3000 {transparent}}
If you're using wildcard subdomains, you will want to use the transparent
prefix for the proxy
directive so it forwards the original hostname to your app like in the example above. You can find more info about that in Caddy's excellent docs.
7. Run Caddy now and every time your system restarts
Terminal
$ brew services start caddy
That's it! If you change your Caddyfile, you will need to brew services restart caddy
.
Thanks to Jason Kulatunga's article Local Development with Wildcard DNS for making it easy to get started with Dnsmasq.
I hope this was helpful to you. If you have any questions, feel free to reach out to me on Twitter!