TL;DR: how do I get a client in my container to make an HTTPS connection to a service on the host?
I've got a service running on a VM on my local dev machine (macOS) that's serving HTTPS on port 8443; it's got a certificate for dev.mycoolproject.com
and dev.mycoolproject.com
has an A
record pointing to 127.0.0.1. So, if I run my client on my local machine and point it to https://dev.mycoolproject.com:8443
it makes a secure connection to my local service.
I want to run my client inside a docker container and still have it connect to that local server on the host. But obviously dev.mycoolproject.com
pointing at 127.0.0.1 won't work, and I can't just use /etc/hosts
to redirect it because the host's IP is dynamic. I can reach the local server at host.docker.internal:8443
, but I'll get TLS errors because the hostname doesn't match.
Is there any way I can get docker's DNS to map dev.mycoolproject.com
to the host IP? I looked into running dnsmasq locally in the container but I had trouble getting it to work.
Containers that use the default bridge network get a copy of this file, whereas containers that use a custom network use Docker's embedded DNS server, which forwards external DNS lookups to the DNS servers configured on the host.
Docker containers take DNS IPs from the host machine, which is managed by systemd-resolve . Those IPs themselves are the cloud provider's DNS.
Accessing the Host With the Default Bridge Mode You just need to reference it by its Docker network IP, instead of localhost or 127.0. 0.1 . Your host's Docker IP will be shown on the inet line. Connect to this IP address from within your containers to successfully access the services running on your host.
DNS nameservers in Docker. Docker is coded in a smart way. When you run new container on the docker host without any DNS related option in command, it simply copies host’s /etc/resolv.conf into container. While copying it filter’s out all localhost IP addresses from the file.
Instead, we use the container name, this is because within Docker containers we don't have to specify the other Docker container's IP address to connect to it we can specify the container name. Docker's DNS will resolve the name into an IP address for us.
In a user-defined docker network, DNS resolution to container names happens automatically. You don’t have to do anything if your containers are using your defined docker network they can find each other with hostname automatically. We have 2 Nginx containers running using my newly created docker network named kerneltalks.
Docker Desktop 18.03+ for Windows and Mac supports host.docker.internal as a functioning alias for localhost. Use this string inside your containers to access your host machine. localhost and 127.0.0.1 – These resolve to the container. host.docker.internal – This resolves to the outside host.
In a container where you might not have access to tools like dig
or nslookup
and don't want to install another 55MB package (like debian's dnsutils) just to get the host.docker.internal
IP it might be better to use getent
instead of dig
:
getent hosts host.docker.internal | awk '{ print $1 }'
I ran into a similar issue yesterday and came up with a workaround that adds an entry to /etc/hosts
resolving to the the host IP.
You'll need dig
or another DNS tool to query for the IP.
If you are running as root you can use:
echo "$(dig +short host.docker.internal) dev.mycoolproject.com" >> /etc/hosts
If you have sudo you can run:
echo "$(dig +short host.docker.internal) dev.mycoolproject.com" | sudo tee -a /etc/hosts
Initially I was hoping the --add-host
run option would allow for special docker entries in the host ip argument (like host.docker.internal
) but unfortunately they don't.
I wanted to avoid more container configuration so I went with this. Setting up dnsmasq
would be a more stable solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With