MongoDB Docker entrypoint behavior not honoured

Hi,

I am a bit perplexed by the behavior I am seeing, that is related to the MongoDB docker entry point, in a very simple Juju test charm (posted to github) created to demonstrate this unexpected behavior.

MonogDB docker image allows enabling authentication by setting a few environment variables. This is documented on their dockerhub page and can also be seen in the corresponding docker entrypoint shell script . These variables specify the username and password of the root user. If these variables are set then on the very first start (but not subsequently) of the docker image, a user with these credentials are created. If this charm is built and deployed, it can be seen that no such user is created, even though the charm sets the environment variables in the Juju pod spec v3. Logging into the application pod it can be seen that the environment variables have been created though. Hence it may seem that there is a bug with the MongoDB docker image. However if the MongoDB docker images is launched by itself, setting these variables on the docker command line then, the user is indeed created.

Here is a sample MongoDB log generated on trying to authenticate after executing a shell in the application pod. It is evident that the log shows an error message saying user was not found.

{"t":{"$date":"2021-03-15T11:32:31.020+00:00"},"s":"I",  "c":"NETWORK",  "id":22943,   "ctx":"listener","msg":"Connection accepted","attr {"remote":"127.0.0.1:45834","connectionId":33,"connectionCount":1}}
{"t":{"$date":"2021-03-15T11:32:31.021+00:00"},"s":"I",  "c":"NETWORK",  "id":51800,   "ctx":"conn33","msg":"client metadata","attr":{"remote":"127.0.0.1:45834","client":"conn33","doc":{"application":{"name":"MongoDB Shell"},"driver":{"name":"MongoDB Internal Client","version":"4.4.4"},"os":{"type":"Linux","name":"Ubuntu","architecture":"x86_64","version":"18.04"}}}}
{"t":{"$date":"2021-03-15T11:32:31.021+00:00"},"s":"I",  "c":"ACCESS",   "id":20251,   "ctx":"conn33","msg":"Supported SASL mechanisms requested for unknown user","attr":{"user":"root@admin"}}
{"t":{"$date":"2021-03-15T11:32:31.021+00:00"},"s":"I",  "c":"ACCESS",   "id":20249,   "ctx":"conn33","msg":"Authentication failed","attr":{"mechanism":"SCRAM-SHA-256","principalName":"root","authenticationDatabase":"admin","client":"127.0.0.1:45834","result":"UserNotFound: Could not find user \"root\" for db \"admin\""}}
{"t":{"$date":"2021-03-15T11:32:31.021+00:00"},"s":"I",  "c":"ACCESS",   "id":20249,   "ctx":"conn33","msg":"Authentication failed","attr":{"mechanism":"SCRAM-SHA-1","principalName":"root","authenticationDatabase":"admin","client":"127.0.0.1:45834","result":"UserNotFound: Could not find user \"root\" for db \"admin\""}}

I will be grateful for any pointers on this issue.

Regards
B Thomas

Further to my post above, I investigated if the issue might be Kubernetes (or microk8s) related. This does not seem to be the case. I used the following statefulsets.yaml and service.yaml to successfully deploy a pod with MongoDB and root user (root) with password (password) as listed in the environment variables created.

statefulsets.yaml : https://pastebin.canonical.com/p/NrqnCT7gkP/
(PS: change nodeselector hostname to suite your local node before deploying)

service.yaml: https://pastebin.canonical.com/p/ZbX2cRvBHk/

After further investigation it turns out the issue seems to be that, command in the Juju pod spec is really the entry point (Docker ENTRYPOINT) rather than command (Docker CMD). So if the pod spec for MongoDB is written as

            "containers": [
            {
                "command": ["/usr/local/bin/docker-entrypoint.sh", "mongod" ... ]
            }

rather than

            "containers": [
            {
                "command": ["mongod" ... ]
            }

then everything works.

Looking here:
https://github.com/docker-library/mongo/blob/272f30b0eb8fdaa48cbfcdfdd1e5e056544295c3/docker-entrypoint.sh#L211

It seems the logic is:
If the env vars are set, or you have an init script, but you don’t have any of the obvious mongod files (WiredTiger, journal, etc), then run the initialization stage.

Is it possible that some of the latter are true? Could you rebuild an image/inject a different startup script that includes some logging so you know which code paths are being used?

By passing the mongod command and all its options as args keyword of Juju container specification the override of the Docker entry point script was avoided. This ensures $OriginalArgOne is mongod and so given the presence of the environment variables the shouldPerformInitdb is set to true. As a result the init scripts in /docker-entrypoint-initdb.dare executed and the root user is created from environment variables.