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:
mongousradmin user is createdmongousradmin password is set to mongopassadmincontainer DB is initializedAny 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
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.
Thanks for the tip, deleting database works for me.
@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.
MongoDB
use DATABASE_NAMEis 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 mydbIf you want to check your databases list, use the command show dbs.
>show dbs local 0.78125GB test 0.23012GBYour 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.
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.
Indeed. The same strange issue is on my side! But do not understand why MONGO_INITDB_DATABASE param is needed if it is overridden by admin DB. Shitty docker. Nothing works as expected. I hate this )
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?
@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
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!
@yosifkit @vutran1710 how are you doing this with docker-compose?
@yosifkit @vutran1710 how are you doing this with
docker-compose?
Switched to Bitnami's mongo.
@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"
}
]
}
);
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?
@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.
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:
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.
@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?
@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.)
@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.
I have filed a new issue to address todays ongoing discussion so please comment and share thoughts there: https://github.com/docker-library/mongo/issues/329
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
/etc folder that contains mongodb.confbind_ip = 127.0.0.1,<Your public ip here>use admindb.auth("<Your root username">,<"Your root password">")db.updateUser("<Your root username">,<"Your NEW root password">")*updating your root password is live and no restarts are required
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.
Switched to Bitnami's mongo.
This comment was hidden as off-topic, but was actually very helpful, thank you @johnwyles vutran1710
For context, I've just spun up half a dozen first party different Docker images for various database (as I'm writing tests for a library that supports a range of backend databases) and the mongo Docker file is the only first party image that didn't make it easy to spin up an instance with read/write access to a named database using username, password and database environment variables.
Most helpful comment
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
--authsince 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 mongodband 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 bashand connect to mongo via localhost in the container to see if you can manually add an initial user.MONGO_INITDB_DATABASEis only used if you have scripts in/docker-entrypoint-initdb.d/since there is noCREATE DATABASE xlike in SQL land; you can just use a database and it will exist.