I do a lot of development, and pretty much run everything locally using Vagrant. For basic stuff http://localhost:3000 is fine, but what happens when I need lots of sub domains or multiple VM's running... here's my journey to solving this problem and some of the suggestions I came across.
The most basic solution that is available is to edit your computers local hosts file. DNS will respect any changes in this file above remote addresses. You can use this to add custom domains each pointing to
127.0.0.1 and they will resolve locally.
Open the file for edit with super user privileges.
$ sudo vim /etc/hosts
You should get something similar to the below
## # Host Database # # localhost is used to configure the loopback interface # when the system is booting. Do not change this entry. ## 127.0.0.1 localhost 255.255.255.255 broadcasthost ::1 localhost fe80::1%lo0 localhost
Don't change the default entries, but you can add as many additional items as you want. Add each entry on a new row (you can use comma separated lists, but I prefer one per row for clarity) in the format
ipaddress <tab> domain
Then save the file. Now if you try to reach that domain, it will resolve to localhost and you can use it in your app.
$ ping myblog.dev PING myblog.dev (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.041 ms 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.089 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.047 ms
The downside to this approach is that you need to edit the hosts file for each domain you want to use, including every subdomain you might want. You can't add wildcard domains to the hosts file.
Another approach that I've seen and tried is to have a real DNS server point at
127.0.0.1. There are a number of domains already set up that offer this, or you can do it yourself if you have a domain/DNS provider.
You can even set up a wildcard DNS record so that all subdomains for a given domain, point to the same IP address and resolve. This will allow you to use your own domain for development.
I'm not posting instructions for this approach as it will differ massively depending on who you host with, but essentially you need to add an A record for
*.yourdomain.tld pointing at
The big downside to this is that you have to be online for it to work. If you are working off-line for any reason, no DNS.
This is my preferred solution. Run a local domain name server on your computer that can resolve all requests for a given top level domain to the localhost, and forward everything else to the Internet as normal.
As with everything I write about this will be specifically aimed at Mac OSX, although you can do the same on Linux as
dnsmasq is available. For Windows users I can't recommend or suggest a service but the principles will be the same.
First off, you will need Homebrew the package manager for OSX. I won't retread installation instructions for it, you can get the most current ones from the Homebrew site.
Then follow these steps, which set up
dnsmasq so that all domains with a TLD of
.loc will point to the localhost
$ brew install dnsmasq $ echo 'address=/.loc/127.0.0.1' > /usr/local/etc/dnsmasq.conf $ sudo cp -v /usr/local/homebrew.mxcl.dnsmasq.plist /Library/LaunchDaemons $ sudo launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
This will install dnsmasq via Homebrew, add the configure value for pointing all
.loc domains to the localhost, add it to the startup process of OS X so dnsmasq is always running, and finally start the service.
You can manually start and stop the service with the following commands
$ sudo launchctl stop homebrew.mxcl.dnsmasq $ sudo launchctl start homebrew.mxcl.dnsmasq
Generally, I will then add
127.0.0.1 as the first domain name server in my network settings. You can do this in
System Preferences -> Network -> Advanced -> DNS
At this point you should be able to use
nslookup to check everything is working and you haven't broken your normal DNS
$ ping google.com PING google.com (18.104.22.168): 56 data bytes 64 bytes from 22.214.171.124: icmp_seq=0 ttl=56 time=5.460 ms 64 bytes from 126.96.36.199: icmp_seq=1 ttl=56 time=6.809 ms $ ping this.is.a.test.loc PING this.is.a.test.loc (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.036 ms 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.068 ms
There you go. A local DNS that will resolve all your local domain needs to