Docker: MongoDB connection slow

published on in category docker , Tags: docker nodejs mongodb macos

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'

I run this site without advertisement of any kind. All information is free and my only goal is to give back something to the amazing free software development community. If you find some value in this, please consider donating me a cup of coffee using PayPal. Thank you so much!