Local development using test domains

Use .test for all your local projects

tech 3 minute read

Most web developers work with their projects locally set up on their laptop to easily test things without having to push changes to a server. I prefer to use docker-compose and the “.test” top level domain so each projects ends up at: “www.project.test”

Problem

When using Docker for local development with multiple projects, you quickly end up with of having to separate your projects only by port numbers. Each project takes up one or more ports on your local machine. Then you have to remember that project1 is running on localhost:8080 and project2 is running on localhost:1234. This setup has many problems, it is not descriptive and also it is unique to each developers machine, qickly ending with conflicts in your docker-compose.yml files for what ports to use.

A quick and easy solution to these problems is to set up test domains for your local projects by manually editing the /etc/hosts file. Then you can use nice host names at least. But for every new project you have to add a custom line, quite tiresome work! A more future proof solution is to forward all *.test domains to your local machine. Sadly the hosts file does not support wildcards.

Previously you might have used .dev for local development, but that domain was bought up by Google in 2014. In 2017 they started enforcing https domain wide, effectively breaking it for local development. There is a very short list of TLDs that are protected from purchase. Out of these I prefer to use .test for local development, as .local is meant for being used in your local network, not your local machine, and .localhost feels too long.

Solution

Run a tiny local DNS server and configure it to automatically resolve any .test domain to localhost. I’ve used dnsmasq for this to great success.

Installation

This installation has been tested on macOS 10.14

  1. Install dnsmasq
    brew install dnsmasq

  2. Configure dnsmasq to listen to all *.test addresses (we are using .test because it is a reserved TLD that will never be bought like .dev)
    mkdir -p $(brew --prefix)/etc && echo 'address=/.test/127.0.0.1' > $(brew --prefix)/etc/dnsmasq.conf

  3. Add dnsmasq to the Mac OS LaunchDaemons to automatically start it at boot, and also start it now, using the simple brew services command
    brew services start dnsmasq

  4. Configure Mac OS built in resolver to use the dnsmasq server first
    sudo mkdir -p /etc/resolver && sudo bash -c 'echo "nameserver 127.0.0.1" > /etc/resolver/test'

  5. Double check you haven’t broken your DNS setup
    ping -c 1 www.ubuntu.com

  6. Any .test domain should now resolve to localhost! Rejoice!
    ping -c 1 this.is.a.test