Last Updated: March 07, 2023
·
38.75K
· athal7

Local docker development with virtual hosts

Problem statement

Using docker is all the rage these days, but there are a few gotchas I ran into when trying to use it locally, most of which can be solved by a virtual host setup. The main advantages of using virtual hosts in local development are:
- No need to worry about port collision/management
- Named URLs e.g. myapp.dev as opposed to localhost:4000

What to do?

Using a mix of dnsmasq and an awesome nginx image with auto-service discovery, we can implement our virtual host setup.

1) Setup dnsmasq: We are going to configure dnsmasq with a local dns resolver to route every request to *.dev to your local docker instance.

brew install dnsmasq # and follow the post-install instructions (or use something else if you prefer)
# Find your docker IP, with docker-machine as 'docker-machine ip', or with docker private beta it is just 127.0.0.1
sudo echo 'address=/dev/YOUR_DOCKER_IP' >> /usr/local/etc/dnsmasq.conf
sudo mkdir -p /etc/resolver
echo 'nameserver 127.0.0.1' | sudo tee /etc/resolver/dev
sudo brew services restart dnsmasq # or restart dnsmasq however you chose to start it
# restart your computer for the local dns resolver to be recognized

2) Add our automated nginx reverse proxy for docker

docker run -d --name nginx -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy

3) Set the VIRTUAL_HOST environment variable on any containers that you want to be accessible via virtual hosts

docker run -e VIRTUAL_HOST=myapp.dev ...

or in docker-compose...

web:
    expose:
        - "8080"
    environment:
      - VIRTUAL_HOST=myapp.dev

As you add more services or start and stop containers, it can be fun to inspect the nginx configuration on the nginx container, as it changes automagically updates based on events in the internal docker api.

And that's it!

I hope you enjoy, and let me know if you have any troubles. Thank you to Jason Wilder for letting us stand on the shoulders of giants.