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.