I’m working on an application where I use Docker and docker-compose to orchestrate a NodeJS container running my backend and a MongoDB container for my database. Using Docker for Mac, I’ve seen drastic slowdowns when initially establishing the database connection. When I used a Linux host, everything was extremely smooth. Since Docker for Mac creates a xhyve-based virtual machine running a Linux with the Docker daemon inside, I initially thought that this is just the usual slow in-VM performance compared to running Docker natively on the host system.
But connecting to the database took almost exactly 30 seconds every attempt, which is extremely annoying when using a watcher to restart the application on every code change.
My setup looked like this:
version: "3"
services:
db:
image: mongo:3.6
command: mongod --smallfiles --bind_ip_all
volumes:
- mongodb-data:/data/db
backend:
build: .
links:
- db
environment:
MONGODB_HOST: 'db'
The first thing I tried was using the internal IP address of the db
container as MONGODB_HOST
environment variable
in the backend
container to bypass name resolution. The connection was created almost instantaneously. But why is
it like this? Changing back to the hostname again brought up the same results like before, almost 30 seconds for the
initial connection.
A look into the /etc/resolv.conf
file of the backend container revealed the problem:
# This file is included on the metadata iso
nameserver 192.168.65.1
search local
domain local
Why do I have search local
and domain local
in that file? This is really strange since Docker containers are not resolved by
container_name.local
but just container_name
.
search local
tricks the container into trying
to resolve db.local
until it fails and only then tries to use the originally supplied hostname. I guess this has some reason
and maybe someone can tell me why it is like this but to me it makes no sense. Maybe this is taken from the settings of
the host system? Because I have local
set as a search domain since I use it on my local network.
Just omitting those two lines would fix the problem in the first place and I cannot see any reason why you would try
to resolve something.local
or anything else on your LAN inside of a Docker container.
The question is, how to fix it? Since I suppose /etc/resolv.conf
is changed based on the network setup, I didn’t
want to override the file contents. Digging through the Compose file reference
I found a property called dns_search
which is responsible for setting search xyz
in /etc/resolv.conf
:
Custom DNS search domains. Can be a single value or a list.
Forcing this to be empty in my docker-compose.yml
fixed the problem and connection is now blazingly fast again, even
on my Mac:
version: "3"
services:
db:
image: mongo:3.6
command: mongod --smallfiles --bind_ip_all
volumes:
- mongodb-data:/data/db
backend:
build: .
dns_search: ''
links:
- db
environment:
MONGODB_HOST: 'db'