I work on a multi-tenant Rails app. Each tenant in the app has bunch of domains and can usually in-turn make use of any sub-domains on those domains. So we don’t have a finite list of domains.
In development, we use .test
TLD instead of whatever the actual TLD is (.com/.net/.org/.etc).
There are already great solutions to resolving .test
domains to localhost whilst also generating correct HTTPS certs so you get HTTPS even in development.
A couple of them that I am aware of are:
- localias
- dev-tld-resolver
- puma-dev - specifically for Puma/Rails apps
- hotel
- chalet
We use puma-dev for our Rails apps. And it works great. However, there’s still one issue: you can only access .test domains from the same machine that’s running your app.
So if you want to debug a issue on Safari on your iPhone, too bad, it won’t work.
In the past, the way I solved this for iOS devices was to use an app called DNSCloak and forward a specific domain to the IP of my machine.
And on the android side, I used personalDNSFilter.
But it was very painful for multiple reasons. These apps don’t support wildcard and having to configure every domain whenever I need to test something was painful. Additionally, I had to always start the app manually to make things resolve correctly.
Resolving .test domains with dnsmasq
A simple way to fix this problem for good without any apps and have things work across all devices on your local network is to set up a custom DNS server.
That’s what I did. We still have puma-dev, but this is just something on top of that for resolving requests from other machines. It’s actually pretty straightforward.
All you need is a machine that’s connected to your local network. It can either be the same machine that’s running your web app or some other device (e.g. a Raspberry Pi).
Setting up dnsmasq
We can setup a DNS server with ease using dnsmasq.
Just install it on your machine (e.g brew install dnsmasq
on OSX), create/open up the config file (/opt/homebrew/etc/dnsmasq.conf
, /etc/dnsmasq.conf
) and add the following:
server=/.test/192.168.100.119
server = 8.8.8.8
server = 8.8.4.4
After you’re done, just start up dnsmasq (something like sudo brew services dnsmasq start
).
What this does is resolve requests for all .test
domains to 192.168.100.119
.
Queries for other domains are forwarded to Google’s DNS servers.
Remember to replace 192.168.100.119
with the IP of the machine that’s running your app.
If your router dynamically assigns an IP to your machine, you can reserve a static IP for your machine. Login to your router’s web interface and there should be a way to reserve a IP for a given MAC address somewhere in the DHCP settings.
Configuring router to use dnsmasq
Most/all routers should allow you to configure a custom DNS server.
Login to your router’s web interface and go to the DNS settings, and set 192.168.100.119
as the DNS server.
Remember to replace 192.168.100.119
with the IP of the machine that’s running dnsmasq.
If everything goes well, you should be able to access your app from any device on your local network. Make sure you bind to 0.0.0.0
when running your app (e.g rails server -b 0.0.0.0
)
That’s all.
Get more articles like this
Subscribe to my newsletter to get my latest blog posts, and other freebies like Treact, as soon as they get published !