How to Add Domains and IP Addresses to Docker Containers

How to Add Domains and IP Addresses to Docker Containers

Overview

Docker users often face challenges with custom domain and IP address mappings in their containers. The inability of containers to read the host machine's /etc/hosts file creates significant obstacles.

In this practical guide, we'll tackle this common Docker networking challenge: how to make containers resolve custom domains and IP addresses without modifying each container individually.

We'll cover two methods: integrating dnsmasq with NetworkManager and configuring dnsmasq without NetworkManager. By the end of this post, you'll be able to easily manage custom domain resolutions in your containers.

By the end of this post, you'll be able to:

  • Easily add custom domain resolutions to all your Docker containers
  • Streamline your development and testing workflows
  • Avoid the headache of managing /etc/hosts files for each container

Table of Contents

  1. Install Dnsmasq
  2. Configure Dnsmasq
    1. Dnsmasq Standalone Usage
    2. Dnsmasq with NetworkManager
  3. Configure Docker
  4. Add Test Domain Names to /etc/hosts
  5. Test the Custom Domain Names

Install Dnsmasq

  • Make sure dnsmasq is installed.
which dnsmasq
  • If not installed, install it
# For Debian / Ubuntu
sudo apt install dnsmasq

# For RHEL / CentOS / Fedora
sudo dnf install dnsmasq

Configure Dnsmasq

Dnsmasq Standalone Usage

In this section, we'll configure dnsmasq if you are not using NetworkManager.

  • Create a new configuration file for dnsmasq:
sudo vim /etc/dnsmasq.conf
  • Add the following configuration options:
# Listen on the Docker bridge interface
interface=docker0

# Specify a default DNS server to forward queries
server=8.8.8.8  # Example: Google DNS
  • Start the dnsmasq service and enable it to run on boot:
sudo systemctl stop dnsmasq && \
sudo systemctl enable --now dnsmasq && \
sudo systemctl status dnsmasq

Dnsmasq with NetworkManager

If you are using NetworkManager, you can use dnsmasq as its plugin.

  • Open NetworkManager main configuration file with an text editor:
sudo vim /etc/NetworkManager/NetworkManager.conf
  • Find the [main] section and add dns=dnsmasq
[main]
dns=dnsmasq
  • Create dnsmasq configuration file in the config daemon directory.
sudo vim /etc/NetworkManager/dnsmasq.d/split-dns.conf
# Listen on the Docker bridge interface
interface=docker0

# Specify a default DNS server to forward queries
server=8.8.8.8  # Example: Google DNS
  • Check if NetworkManager is running without no problem.
sudo systemctl restart NetworkManager && \
sleep 5 && \
sudo systemctl status NetworkManager
  • If there are problems, check the NetworkManager logs.
journalctl -u NetworkManager -r

Configure Docker

  • Check the IP address of the docker0.
ip a show docker0
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:a9:72:e1:3a brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:a9ff:fe72:e13a/64 scope link
       valid_lft forever preferred_lft forever
  • Configure Docker to use the Dnsmasq
sudo vim /etc/docker/daemon.json
{
  "dns": ["172.17.0.1"]
}
  • Restart the docker service
sudo systemctl restart docker 

Add Test Domain Names to /etc/hosts

For testing purposes, add a domain to /etc/hosts.

sudo bash -c "echo '192.168.1.12 nonexisting.example.com' >> /etc/hosts"

Restart the dnsmasq service to get updates.

sudo systemctl restart dnsmasq

Test the Custom Domain Names

In the /etc/hosts file, we defined nonexisting.example.com as 192.168.1.10.

Lets test if the configuration works as expected.

docker run --rm --name dns-test busybox nslookup nonexisting.example.com

The output should be:

Server:		172.17.0.1
Address:	172.17.0.1:53

Non-authoritative answer:

Non-authoritative answer:
Name:	example.com
Address: 192.168.1.10

Viola, you can set any custom domain name in the /etc/hosts file on the host machine and containers will use it by default.