Managing a Local Domain dev to Address Multiple Docker Containers¶
Overview¶
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
Goals¶
I want to set up a local domain dev, to map local subdomains to docker containers, when called from the web browser:
elmar.dev => 192.168.56.2:8000
ehfaq.dev => 192.168.56.2:8001
esp.dev => 192.168.56.2:8002
[...]
The IP 192.168.56.2
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.
Conception¶
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 127.0.0.1, 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 127.0.0.1 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.
address=/dev/127.0.0.1
Test that the DNS server is working.
dig test.dev @127.0.0.1
The following are to be expected with a working setup.
;; ANSWER SECTION:
test.dev. 0 IN A 127.0.0.1
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
nameserver 127.0.0.1
EOF
Check cat /etc/resolver/dev
answers nameserver 127.0.0.1
.
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 www.google.com
# Check that .dev names work
ping -c 1 test1.dev
ping -c 1 test2.dev
All *.dev
domains should now direct to 127.0.0.1.
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.
defaults
mode http
timeout connect 1000ms
timeout client 50000ms
timeout server 50000ms
listen stats
bind 0.0.0.0:9999
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
http://192.168.56.2:8000
displays the local page Elmar Hinz.
Now I want to map it to http://elmar.dev
and similar for other
Dockers.
The minimal configuration looks like this.
global
daemon
defaults
mode http
timeout connect 1000ms
timeout client 50000ms
timeout server 50000ms
frontend http-in
bind *:80
acl is_site1 hdr_end(host) -i elmar.dev
acl is_site2 hdr_end(host) -i ehfaq.dev
acl is_site3 hdr_end(host) -i esp.dev
use_backend elmar if is_site1
use_backend ehfaq if is_site2
use_backend esp if is_site3
backend elmar
server elmar 192.168.56.2:8000
backend ehfaq
server ehfaq 192.168.56.2:8001
backend esp
server esp 192.168.56.2:8002
listen stats
bind 0.0.0.0:9999
stats uri /
To make it listen to port 80, I need to start it as superuser.
sudo haproxy -f ~/.haproxy.conf
Hint
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.