A very handy development option is to have multiple virtual hosts set up for your various projects. This means that you can set up names such as project-x.mydomain.com for a project-specific URL.

Apache generally performs name-based matching, so you don't need to configure multiple IP addresses. Detailed information can be found on the apache.org site.

6.1 Virtual Hosts

Apache already comes preconfigured to support this behavior but it is not enabled. First you will need to uncomment the following lines in: /usr/local/etc/apache2/2.4/httpd.conf

LoadModule vhost_alias_module libexec/mod_vhost_alias.so

and:

# Virtual Hosts
Include /usr/local/etc/apache2/2.4/extra/httpd-vhosts.conf

Then you can edit this referenced file and configure it to your needs.

@ .bashrc

# Manage Virtual Hosts
alias conf_vhosts="sublime /private/etc/hosts && sublime /usr/local/etc/apache2/2.4/extra/httpd-vhosts.conf"

This file has some instructions already but the important thing to remember is that these rules are matched in order.

When you set up virtual hosts, you will lose your older document root, so you will need to add back support for that first as a virtual host.

@ httpd-vhosts.conf

<VirtualHost *:80>
    DocumentRoot "/Users/your_user/Sites"
    ServerName localhost
</VirtualHost>
 
<VirtualHost *:80>
    DocumentRoot "/Users/your_user/Sites/this-site"
    ServerName this-site.com
</VirtualHost>

This just lets you know that the source directory listed for your virtual hosts is not present on the drive. It's an issue that can be resolved by editing this file with the corrected DocumentRoot.

6.2 Dnsmasq

Note - not implemented on my server

In the example virtualhost we setup above, we defined a ServerName of this-site.com.

This by default will not resolve to your local machine. Make it so by manually adding entries to /etc/hosts every time you define a new server for a new site.

@ hosts

127.0.0.1    this-site.com
127.0.0.1    www.this-site.com

However when managing a large number of sites this becomes tedious.

One option is to install and configure Dnsmasq to automatically handle wildcard *.dev names and forward all of them to localhost (127.0.0.1).

First we install it with brew:

brew install dnsmasq

To configure dnsmasq, copy the example configuration to /usr/local/etc/dnsmasq.conf and edit to taste.

cp /usr/local/opt/dnsmasq/dnsmasq.conf.example /usr/local/etc/dnsmasq.conf

Then we setup *.dev hosts:

Add dnsmasq.conf to the conf_hosts definition

@.bashrc

# Manage Virtual Hosts
alias conf_vhosts="sublime /private/etc/hosts && sublime /usr/local/etc/apache2/2.4/extra/httpd-vhosts.conf && /usr/local/etc/dnsmasq.conf"

edit dnsmasq.conf

echo 'address=/.dev/127.0.0.1' > /usr/local/etc/dnsmasq.conf

Start it and ensure it auto-starts on reboot in the future:

sudo brew services start dnsmasq

And lastly, add it to the resolvers:

sudo mkdir -v /etc/resolver
sudo bash -c 'echo "nameserver 127.0.0.1" > /etc/resolver/dev'

Now you can test it out by pinging some bogus.dev name:

ping bogus.dev

returns:

PING bogus.dev (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.044 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.118 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.045 ms

Voila! we have successfully setup wildcard forwarding of all *.dev DNS names to localhost.