mongo: Initialize admin username/password and DB doesn't seems to be working ...

I am using some features from this PR https://github.com/docker-library/mongo/pull/145 (which is not documented BTW 😃 ) but it seems not to be working since I am getting the following error from my application:

2017-04-26T13:24:16.329+0000 I ACCESS [conn3] SCRAM-SHA-1 authentication failed for mongousradmin on admin from client 172.18.0.2:35298 ; UserNotFound: Could not find user mongousradmin@admin

This is how my docker-compose.yml file looks like:

version: '3'
services:
  webserver:
    image: reynierpm/docker-lamp:latest
    ports:
      - "80:80"
    volumes:
      - ~/sources:/var/www/html
  mongodb:
    image: mongo:latest
    env_file: .env
    environment:
      MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME}
      MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
      MONGO_INITDB_DATABASE: ${MONGO_INITDB_DATABASE}
    ports:
      - "27017:27017"

And the .env file has this content:

#MongoDB Default Setup
MONGO_INITDB_ROOT_USERNAME=mongousradmin
MONGO_INITDB_ROOT_PASSWORD=mongopassadmin
MONGO_INITDB_DATABASE=container

From my understanding and the PR code I would expect:

  • an mongousradmin user is created
  • the mongousradmin password is set to mongopassadmin
  • an empty container DB is initialized

Any ideas about what could be wrong here? If I remember correct right after the PR was approved I test this and was working so either I am missing something or isn’t working anymore

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 46
  • Comments: 22 (4 by maintainers)

Most upvoted comments

@vutran1710 I was able to solve it with the default mongo docker image by adding this to docker-compose.yml:

  mongo:
    environment:
      MONGO_INITDB_DATABASE: mydatabase
      MONGO_INITDB_ROOT_PASSWORD: password
      MONGO_INITDB_ROOT_USERNAME: admin
    hostname: mongodb-server
    image: mongo
    ports:
      - "27017:27017"
    restart: always
    volumes:
      - ./data/mongo/001_users.js:/docker-entrypoint-initdb.d/001_users.js:ro
      - mongodb:/data/db
      - mongodb_config:/data/configdb

And then adding the following to data/mongo/001_users.js:

db.createUser(
    {
        user: "admin",
        pwd: "password",
        roles:[
            {
                role: "readWrite",
                db:   "mydatabase"
            }
        ]
    }
);

Was your database already created? The env vars will not create a user on an already created database, but they do ensure mongod is started with --auth since you need it even after the first start. Docker-compose tries really hard to preserve your data volumes between container recreations.

If there is nothing important in there you can always docker-compose rm -fv mongodb and try again.

If you need the data, you can see if there are actually any users created; jump into the container with a docker exec -it mongo-container-name bash and connect to mongo via localhost in the container to see if you can manually add an initial user.

MONGO_INITDB_DATABASE is only used if you have scripts in /docker-entrypoint-initdb.d/ since there is no CREATE DATABASE x like in SQL land; you can just use a database and it will exist.

@tianon I agree with @johnwyles - the reason so many of us (and lots more on StackOverflow) misunderstoof #145 is that it describes obviously necessary behavior, which we need - but the actual behavior isn’t useful.

There should be a way to easily create a preconfigured container, with a new database with a username and password, via docker-compose.

Doing this via an extra js files isn’t sensible because

  1. this is something so simple and obvious, it is not an out of the ordinary use case
  2. the point of the config file is to centralize config, but now we have more config in more files, it’s messy
  3. we need to duplicate config in the compose file and the js file (error prone!)

At the very least the docs should cover this use case and show comment 174 as an official solution. (Until hopefully the behavior we need is added.)

mongo_1  | Successfully added user: {
mongo_1  |      "user" : "root",
mongo_1  |      "roles" : [
mongo_1  |              {
mongo_1  |                      "role" : "root",
mongo_1  |                      "db" : "admin"
mongo_1  |              }
mongo_1  |      ]
mongo_1  | }

I’ve been stuck on this for a while, but I think I figured it out. The mongo instance defaults to test database however the database where the username and password you create is on the admin database. You’re able to switch databases using ‘use admin’ and then authenticating will work.

@tianon This is probably now more of a Mongo question but if I were to only supply:

MONGO_INITDB_DATABASE: mydatabase
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_ROOT_USERNAME: admin

And then leave out:

- ./data/mongo/001_users.js:/docker-entrypoint-initdb.d/001_users.js:ro

Would I be able to authenticate against the DB? What if I wanted a mydatabase created? I would need my application to create the database? If my application creates the database does it have to use the MONGO_INITDB_ROOT_PASSWORD, and MONGO_INITDB_ROOT_USERNAME credentials in order to do so?

Last question: what is MONGO_INITDB_DATABASE for? I thought if I set the following:

MONGO_INITDB_DATABASE: mydatabase
MONGO_INITDB_ROOT_PASSWORD: password
MONGO_INITDB_ROOT_USERNAME: admin

That it would create a database named mydatabase with a username of admin and a password of password. What is going on instead then?

@yosifkit re-reading through all of your comments I do not think you seem to fully understand the issue that myself and all the others on this issue have discussed and @lonix1 and myself have found the fix I mentioned above.

The point here is not to get on the docker image and play around with the user that is created, not to login or get a shell on the docker image, not to run ANY pre or post mongo commands whatsoever on the container but for the docker container to simply start mongo already initialized with an administrative username and password. That is it. There is nothing more to the issue and the point here is that it appears that NONE of the environment variables MONGO_INITDB_ROOT_USERNAME, MONGO_INITDB_ROOT_PASSWORD, and MONGO_INITDB_DATABASE seem to be respected or used despite that being the indication in https://github.com/docker-library/mongo/pull/145 so can you please answer directly with a copy of a docker-compose.yml file which you have that will work to launch a mongo container already initialized with a administrative username and password set. I do not like the solution I provided and would prefer something much simpler like https://github.com/docker-library/mongo/pull/145 suggests is possible.

mongo_1  | Successfully added user: {
mongo_1  |      "user" : "root",
mongo_1  |      "roles" : [
mongo_1  |              {
mongo_1  |                      "role" : "root",
mongo_1  |                      "db" : "admin"
mongo_1  |              }
mongo_1  |      ]
mongo_1  | }

I’ve been stuck on this for a while, but I think I figured it out. The mongo instance defaults to test database however the database where the username and password you create is on the admin database. You’re able to switch databases using ‘use admin’ and then authenticating will work.

Totally agree with you. This is pure evil! Wasted 5 freaking hours of my life!

MongoDB use DATABASE_NAME is used to create database. The command will create a new database if it doesn’t exist, otherwise it will return the existing database

>use mydb
switched to db mydb

If you want to check your databases list, use the command show dbs.

>show dbs
local     0.78125GB
test      0.23012GB

Your created database (mydb) is not present in list. To display database, you need to insert at least one document into it.

- https://www.tutorialspoint.com/mongodb/mongodb_create_database.htm

Once you insert something in the database it will show up, otherwise you can just use any “database” that you want.

For those who are still having issues for not being able to change their root password/username after supplying the environment variables (Works for me):

  1. Jump into your dockerized MongoDB container with docker exec -it <mongo-container-name or mongo-container-id> bash
  2. Connect to mongodb/mongod service locally inside your docker container with mongo 127.0.0.1
  • Do note that the mongodb container has a local/private ip binded to it and can be found in /etc folder that contains mongodb.conf with a line that mentions bind_ip = 127.0.0.1,<Your public ip here>
  1. Inside the mongo shell in the mongodb container, jump to the admin database with use admin
  2. Authenticate yourself with the last known root username and password like db.auth("<Your root username">,<"Your root password">")
  3. After authenticating yourself, update your desired new root password with db.updateUser("<Your root username">,<"Your NEW root password">")

*updating your root password is live and no restarts are required

What was implemented in #145 was the ability to create a “root” user with superuser access to the entire MongoDB instance using only environment variables:

https://github.com/docker-library/mongo/blob/5ab118c15c474192dc6ab058e5cb370b73ced636/docker-entrypoint.sh#L291-L301

It is created with an explicit “role” of root and an explicit “db” of admin, hence the need to specify --authenticationDatabase when using this pre-canned behavior of the image.

Given that authentication is very flexible in MongoDB, we did not want to overcomplicate the initialization script with more than that bare minimum behavior. If something more complex or customized is required, that’s exactly what /docker-entrypoint-initdb.d is for (which can contain either .js files or .sh files, depending on how complicated you need the custom initialization behavior to be), as demonstrated in https://github.com/docker-library/mongo/issues/174#issuecomment-449984230.

The only thing I would suggest changing there is to remove the use of the MONGO_INITDB_ROOT_* variables, since the 000_users.js file is responsible for creating them with appropriate permissions to a single explicit database with admin permissions instead of root permissions.

Like everyone else here, I did the same as the OP and it did not work. But the solution posted by @johnwyles does work.

So is the documentation wrong? Which is the officially supported way - the OP’s code, or the docker-entrypoint-initdb.d/001_users.js?