Managing a Local Domain dev to Address Multiple Docker Containers


I keep my TYPO3 projects in Docker containers on a Macbook Pro. Docker containers live inside a Linux machine. My Linux is a virtual machine controlled by Vagrant, also addressed as Vagrant box. This setup results in three nested OS levels:

OS X -> Ubuntu -> Dockers


I want to set up a local domain dev, to map local subdomains to docker containers, when called from the web browser: => => =>

The IP is my Vagrant box, that hosts the Docker containers. Each project lives in it’s own Docker container suite and is accessible by it’s onw set of ports on the Vagrant machine.

Running Multiple Instances in Parallel explains how to set up the Docker suites to be able to run them in parallel with dedicated ports each.


The file /etc/hosts doesn’t work with an asterix with OS X. By a file named /etc/resolver/dev I can register the address, the address of a local DNS, for the top level domain dev.

Dnsmasq is the choice, as it is easily installed by Homebrew and as easily to configure. In this case all it needs to do, is to serve the address for all subdomains of dev, as we need a proxy for the next step.

Differnt ports of the Vagrant machine shall serve for different domain names. This is out of the service of a DNS. A proxy can do this. My choice is Haproxy, again easily to install by Homebrew and easily to configure.

Getting the Local DNS Working

This part is a summary of a tutorial written by Thomas Sutton. Read it for an extended description.

Installing Dnsmasq

I install with Homebrew.

brew update
brew upgrade
brew install dnsmasq
man dnsmaq

The Homebrew installation process outputs some help to get me started. The actual paths depend on the systems setup:

To configure dnsmasq, copy the example configuration to /Users/ElmarHinz/Homebrew/etc/dnsmasq.conf and edit to taste.
   cp /Users/ElmarHinz/Homebrew/opt/dnsmasq/dnsmasq.conf.example /Users/ElmarHinz/Homebrew/etc/dnsmasq.conf

To have launchd start dnsmasq at startup:
   sudo cp -fv /Users/ElmarHinz/Homebrew/opt/dnsmasq/*.plist /Library/LaunchDaemons
   sudo chown root /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist

Then to load dnsmasq now:
   sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist

WARNING: launchctl will fail when run under tmux.

I follow the advices, how to place the configuration files and how to start the service. There is only one entry to put into the dnsmasq.conf file.


Test that the DNS server is working.

dig @

The following are to be expected with a working setup.

;; ANSWER SECTION:               0       IN      A

Configuring OS X

The domain dev get’s a dedicated resolver file in the directory /etc/resolver. If it doesn’t already exists, it needs to be created first. Then the mapping is written into it.

sudo mkdir -p /etc/resolver
sudo tee /etc/resolver/dev >/dev/null <<EOF

Check cat /etc/resolver/dev answers nameserver

Testing the DNS

I can use ping to check, if both parts play well together.

# Make sure I haven't brocken my DNS.
ping -c 1
# Check that .dev names work
ping -c 1
ping -c 1

All *.dev domains should now direct to

Getting the Proxy Working

Installing Haproxy

I install with Homebrew.

brew install haproxy
man haproxy

I create a configuration file. There is no default path for it.

touch ~/.haproxy.conf

I edit the configuration file to get a minimal response.

    mode http
    timeout connect 1000ms
    timeout client 50000ms
    timeout server 50000ms

listen stats
    stats uri /

I start the service for testing.

haproxy -f ~/.haproxy.conf

I visit the URL http://localhost:9999 to the Statistics Report running.

Pressing CTRL-C to stop.

Configuring the Domains

Vagrant and the Dockers are running. Calling displays the local page Elmar Hinz. Now I want to map it to and similar for other Dockers.

The minimal configuration looks like this.


    mode http
    timeout connect 1000ms
    timeout client 50000ms
    timeout server 50000ms

frontend http-in
    bind *:80

    acl is_site1 hdr_end(host) -i
    acl is_site2 hdr_end(host) -i
    acl is_site3 hdr_end(host) -i

    use_backend elmar if is_site1
    use_backend ehfaq if is_site2
    use_backend esp if is_site3

backend elmar
    server elmar

backend ehfaq
    server ehfaq

backend esp
    server esp

listen stats
    stats uri /

To make it listen to port 80, I need to start it as superuser.

sudo haproxy -f ~/.haproxy.conf


It is configured as a daemon now and will continue running in the background. For now I use to commands ps aux | grep haproxy and sudo kill -9 [process id] to find and stop it.