where I introduce devproxy

Have you ever heard of Pow? It’s a little node.js app which allows you to use the .dev domain for Rack apps. Sounds awesome, but:

But this .dev domain thing is really cool for making apps which use subdomains and editing /etc/hosts is awful, painful and whatever. Could there be a better solution?

Yeah! dnsmasq and devproxy.

  1. Install dnsmasq (brew install dnsmasq for OS X)
  2. Install npm
  3. npm install -g devproxy
  4. Copy your resolv.conf somewhere, eg.

    cp /etc/resolv.conf /usr/local/etc/resolv.conf
    
  5. Configure dnsmasq – you need it to point to this resolv.conf and make it resolve *.dev to localhost:

    address=/.dev/127.0.0.1
    resolv-file=/usr/local/etc/resolv.conf
    
  6. touch ~/.devproxy

  7. Set up dnsmasq and devproxy to start automatically with your system. On OS X, this is done with LaunchAgents. Homebrew installs one with dnsmasq. Now you have to symlink devproxy’s one:

    ln -s /usr/local/lib/node_modules/devproxy/com.floatboth.devproxy.plist ~/Library/LaunchAgents/
    
  8. Start them now. On OS X, lunchy is a good wrapper around launchctl. lunchy start dnsmasq and lunchy start devproxy – much better than passing full paths to launchctl

  9. Put nameserver 127.0.0.1 in /etc/resolv.conf if you’re not on OS X, which will overwrite this file through GUI, so you have to change it in network settings (Advanced, DNS):

    Screenshot

  10. Set up forwarding from port 80 to 8999 – launch devproxy, copy and paste the appropriate command (iptables for Linux, ipfw for *BSD, OS X)

  11. Don’t forget to update /usr/local/etc/resolv.conf when your DNS servers change. On OS X, that would be removing 127.0.0.1 in the settings, saving, overwriting /usr/local/etc/resolv.conf with /etc/resolv.conf and adding it back.

To add a domain:port mapping, append it to ~/.devproxy, eg, echo "floatboth.dev:4000" >> ~/.devproxy. Now, floatboth.dev (port 80) resolves to localhost:4000. Any .dev domains not in ~/.devproxy resolve to port 3000.

Little bonus: now you have local DNS caching!

UPDATE: you can just do this (on OS X) instead of steps 4, 9 and 11, and step 5 would use resolv-file=/etc/resolv.conf

sudo mkdir /etc/resolver
echo 'nameserver 127.0.0.1' | sudo tee /etc/resolver/dev

Thanks, Stig. This method doesn’t give you local caching, but also doesn’t give you pain in the ass when switching Wi-Fi networks. By the way, it’s your router’s job to cache DNS – DD-WRT custom firmware includes dnsmasq too.