jakekara.com

Tripping up on Mongo Docker's use of ENTRYPOINT and CMD

When using the official Mongo Docker image, I ran into a problem that had me scratching my head for a while.

The problem

When I ran:


    $ docker run --network app-net -p 27017:27017 mongo

I was able to connect to the DB from my host (or another container on the “app-net” network).

However, when I ran:


    $ docker run --network app-net -p 27017:27017 mongo /bin/sh -c "mongod"

The server appeared to start up and listen for connections, but the service was unreachable from the host or other containers.

When I wanted to add extra initialization steps, like fetching and restoring a database, I thought that as long as I used the command mongod to invoke the server, I’d be good. Nope…

Understanding the problem

It turns out that the official Dockerfile uses a combination of ENTRYPOINT and CMD. This causes the value of CMD, which is ["mongod"] to be passed as an argument array to the value of ENTRYPOINT, which in this case is a helper script. So, when using docker run with no command, the ENTRYPOINT script runs with the argument mongod. What ends up being run is the equivalent of docker-entrypoint.sh mongo.

The solution

The solution for me was to make sure I call docker-entrypoint.sh mongod when I’m ready to launch the server process, whether from the command line or in the Dockerfile.

Takeaway

The use of ENTRYPOINT for this purpose is entirely in line with recommended practices, but it wasn’t obvious to me right away what was going on without looking at the Dockerfile.

In this way, working with Docker images isn’t as straightforward as using a software library, where all you have to learn is the interface and can ignore the implementation details. Sometimes you have to get more under the hood.