0

everyone,

I'm having a hard time setting up a MongoDB container to have root password and creating a new user with less privileges (that will be my application user) automatically.

Ideally I should have only some scripts and a docker-compose configuration.

I tried adding the MONGO_INITDB_ROOT_USERNAME and MONGO_INITDB_ROOT_PASSWORD but they don't seem to work. They do something, because when I start the container like that, I can't just connect to the mongo shell and run all the commands (and passing username and password will throw unauthorized errors).

Then I thought about adding a script at /docker-entrypoint-initdb.d/ but they dont seem to run. They don't show on console. Besides, i just put a javascript like this and I am not sure whether they will work:

var db = connect("mongodb://localhost/admin");

db.createRole(
    {
        role: "somerole",
        privileges: [
            {
              actions: [ "find", "update", "insert" ],
              resource: { db: "mydb", collection: "" } <--- does it means all colections od database mydb?!?!
            }
          ],
        roles: [  ]
    }
)

db.createUser(
    {
        user: "admin",
        pwd: "adminpass",
        roles: [ { role: "userAdminAnyDatabase", db: "mydb" } ]
    }
)

db.createUser(
    {
        user: "system",
        pwd: "systempass",
        roles: [ { role: "somerole", db: "mydb" } ]
    }
)

I would also want to create collections and insert documents. How do we do that? Shouldn't it be with entrypoints!?

Victor Ferreira
  • 6,151
  • 13
  • 64
  • 120

2 Answers2

5

MongoDb Documentation: Security Reference

Partial response 1

Partial response 2

1) Create the following structure of files:

enter image description here

2) Content of docker-compose.yml

version: "3"
services:
  mongodb:
    image: "mongo:4.1.1-xenial"
    restart: "unless-stopped"
    env_file:
     - ".env"
    ports:
     - "27017:27017"
    volumes:
     - "./database/data:/data/db"                           # Database files
     - "./database/fixtures:/docker-entrypoint-initdb.d"    # To create Db at start

3) Content of default.js

/* Create a New user with "only READ" role */
db = db.getSiblingDB('admin');
db.createUser(
{ 
  "user": "John",
  "pwd": "MyPassword",
  "roles": [
     { "role": "read", "db": "data" } 
  ]
})
/* Misc - Other Data */
db = db.getSiblingDB('data');
db.data.save([
    {
        "name": "Frank",
        "email": "email1@gmail.com",
    },
    {
        "name": "Peter",
        "email": "email2@gmail.com",
    }
  ]);

4) Content of .env

MONGO_INITDB_ROOT_USERNAME=Robert
MONGO_INITDB_ROOT_PASSWORD=GoodPassword

5) Go to your terminal and at the level of the docker-compose.yml file, execute:sudo docker-compose up -d

6) Get the container's name:

Execute: sudo docker ps a

7) Go inside the container:

Execute: sudo docker exec -it <CONTAINER NAME> bash

8) Inside the container:

Execute: mongo --host localhost -u Robert -p GoodPassword --authenticationDatabase admin

NOTE: Take into account that we are specifying the "authentication database"

9) Select database:

Execute: use admin

10) Show users (You must find two users Robert and John):

Execute: show users

As you can see inside "data" directory are stored the files of the database.

And using the default.js file you can create collections frm the start.

IMPORTANT NOTE: If you make some changes and those are not reflected to the database, then you need to DELETE the content of "data" and run again: docker-compose up -d

We can say that, if "data" directory is not empty, then the "default.js" file will not be taked into account.

pablodonayre
  • 104
  • 1
  • 5
  • hey I can create the user, but I can't connect to the database with the application. it keeps saying John@data (i'm trying to connect to the data database) – Victor Ferreira May 27 '19 at 21:24
  • Can you connect with COMPASS to the database ? How are you trying to connect (specify your connection command) ? Can you connect using step 8 ? Paste your "Error" response – pablodonayre May 28 '19 at 06:14
  • life saving answer, need to delete all the content in data, then only it can take effect to the changes – ken Dec 05 '21 at 06:43
0

I changed a bit your configuration and it runs correctly:

docker-compose.yml:

version: '3.1'

services:

  mongo:
    image: mongo
    restart: always
    volumes:
      - ./init.js:/docker-entrypoint-initdb.d/init.js
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: example
      MONGO_INITDB_DATABASE: mydb

here I specify the database to be created initially and I also mount the init script.

init.js:

var db = connect("mongodb://localhost/mydb");

db.createRole(
    {
        role: "somerole",
        privileges: [
            {
              actions: [ "find", "update", "insert" ],
              resource: { db: "mydb", collection: "" }
            }
          ],
        roles: [  ]
    }
)

db.createUser(
    {
        user: "admin",
        pwd: "adminpass",
        roles: [ { role: "somerole", db: "mydb" } ]
    }
)

db.createUser(
    {
        user: "system",
        pwd: "systempass",
        roles: [ { role: "somerole", db: "mydb" } ]
    }
)

The important part here is the first line, otherwise you create a role in the admin database while you look for it in mydb database.

With this setup I can start the database and connect to it.

Mihai
  • 9,526
  • 2
  • 18
  • 40