This project contains the files for implementing a local containerized infrastructure with internal DNS-based service resolution with BIND and HAProxy acting as a Layer 7 (HTTP) load balancer. This simulates a near production scenario for service discovery and routing setup.
To implement this project you would only need Docker installed rest are the images that will be pulled by Docker
docker network create --subnet=192.168.100.0/24 internal_netThis creates a network named internal_net which has the hostnames defined for our servers BIND,Web & HAproxy.
docker-compose up -dThis builds and launches all the containers in detached mode.
This Lists all the running containers,you can verify if all are running
docker psIn this infrastructure DNS is used to resolve internal service names like web1.internal.lan,web2.internal.lan to real internal IP addresses like 192.168.100.21 or 192.168.100.22.
This decouples service names from IPs, allowing HAProxy to dynamically discover services without hardcoding them. For example in the file db.internal.lan web1 IN A 192.168.100.21 web2 IN A 192.168.100.22 This tells BIND: “If someone asks for web1.internal.lan, respond with 192.168.100.21.”
In Docker, the bind container has a fixed IP like 192.168.100.10. It listens on port 53 for DNS queries from inside the network. You can check if your BIND DNS container directly to resolve web1.internal.lan
dig @192.168.100.10 web1.internal.lanTo test the load balancing feature enter
curl http://localhostThis sends an HTTP request to HAProxy on port 80, which routes it to web1 or web2.When HAProxy needs to connect to web1.internal.lan, it performs a DNS lookup using the dns_resolver configuration.This request goes to BIND over the internal Docker network. When you enter the curl command
curl http://localhostthe HAproxy accepts the Http request since its operating on L7 mode,it parses the full HTTP request to URL path,HTTP headers,Methods(GET,POST,etc.)
web1-1 and web2-1 running Nginx containers each is listening on port 80 inside the container but not exposed directly to the host (they're only reachable by HAProxy)it resolves web1.internal.lan and web2.internal.lan via BIND9 DNS.This lets you dynamically register, scale, or replace services without hardcoding IPs.
To check logs
docker ps //List all running containers
docker logs -f haproxy //view live logs for haproxy service
docker exec -it bind tail -f /var/log/named/named.log //Live DNS logs