Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialize admin username/password and DB doesn't seems to be working ... #174

Closed
mmi-rperez opened this issue Apr 26, 2017 · 22 comments
Closed

Comments

@mmi-rperez
Copy link

I am using some features from this PR #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

@yosifkit
Copy link
Member

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.

@xgdgsc
Copy link

xgdgsc commented Apr 29, 2017

Thanks for the tip, deleting database works for me.

@reypm
Copy link

reypm commented May 6, 2017

@yosifkit ...

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.

I don't think so since I did a docker system prune -af before run docker-compose up

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

Yes, there nothing is important - for now - so I can try the given command

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.

This is not necessary, in this scenario data is useless to me.

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.

I am not sure to be understanding what the issue is here but if I am getting you correct then I need to have some scripts under /docker-entrypoint-initdb.d/ or the default MONGO_INITDB_DATABASE will be never created? What about if I want to initialize the instance with an empty database but I don't want to create any collection? For me that case is valid since the application will care about the collections and so on.

@yosifkit
Copy link
Member

yosifkit commented May 9, 2017

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.

@Legitcoder
Copy link

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.

@kostyanius

This comment has been minimized.

@letavia
Copy link

letavia commented Sep 17, 2018

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.

How did you do this to be precise?

@yosifkit
Copy link
Member

@letavia, you just need to set the authenticationDatabase.

From the env vars section of the docs on docker hub,

$ docker run -it --rm --link some-mongo:mongo mongo mongo --host mongo -u mongoadmin -p secret --authenticationDatabase admin some-db

To make it a little simpler, lets skip the link and assume you have a hostname of my-mongo to access MongoDB:

$ docker run -it --rm mongo:4.0 mongo --host my-mongo -u mongoadmin -p secret --authenticationDatabase admin mydbname
# or
$ docker run -it --rm mongo:4.0 -u mongoadmin -p secret --authenticationDatabase admin mongo my-mongo/mydbname

@vutran1710
Copy link

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!

@johnwyles

This comment has been minimized.

@vutran1710

This comment has been minimized.

@johnwyles
Copy link

@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"
            }
        ]
    }
);

@lonix1
Copy link

lonix1 commented Feb 4, 2019

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?

@johnwyles
Copy link

johnwyles commented Feb 4, 2019

@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 #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 #145 suggests is possible.

@tianon
Copy link
Member

tianon commented Feb 4, 2019

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:

mongo/docker-entrypoint.sh

Lines 291 to 301 in 5ab118c

if [ "$MONGO_INITDB_ROOT_USERNAME" ] && [ "$MONGO_INITDB_ROOT_PASSWORD" ]; then
rootAuthDatabase='admin'
"${mongo[@]}" "$rootAuthDatabase" <<-EOJS
db.createUser({
user: $(_js_escape "$MONGO_INITDB_ROOT_USERNAME"),
pwd: $(_js_escape "$MONGO_INITDB_ROOT_PASSWORD"),
roles: [ { role: 'root', db: $(_js_escape "$rootAuthDatabase") } ]
})
EOJS
fi

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 #174 (comment).

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.

@johnwyles
Copy link

@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?

@lonix1
Copy link

lonix1 commented Feb 5, 2019

@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.)

@lonix1
Copy link

lonix1 commented Feb 5, 2019

@johnwyles BTW it only works for me if I keep the MONGO_INITDB_DATABASE, MONGO_INITDB_ROOT_PASSWORD and MONGO_INITDB_ROOT_USERNAME. The advice seems to be to get rid of them because they are for a different purpose, but if I do that then your method fails. So they stay.

So basically, unless I am misunderstanding this problem (and if I am it's not my fault because the docs are not clear), this entire feature is problematic.

@johnwyles
Copy link

I have filed a new issue to address todays ongoing discussion so please comment and share thoughts there: #329

@Acerizm
Copy link

Acerizm commented May 20, 2019

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

@johnwyles
Copy link

Thank you @Acerizm - if #329 could have it's PRs merged or at least it would be communicated very clearly and concisely where it falls short so that it may be merged.

@iaincollins

This comment has been minimized.

@docker-library docker-library locked as resolved and limited conversation to collaborators May 25, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests