Docker compose mongo wont create root user - mongodb

I am trying to create to compose a docker container with a mongo image. I want the container to have a root user called admin and also be able to create a database called experts_db. Here is my docker-compose.yaml:
version: '3.7'
services:
mongodb:
image: mongo:4.0.4
container_name: mongodbtest
restart: always
env_file: .env
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: 123456789
MONGO_INITDB_DATABASE: experts_db
ports:
- 27017:27017
volumes:
- ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
and here is my mongo-init.js file:
use admin;
db.createUser(
{
user: "andrea",
pwd: "123456789",
roles: [
"userAdminAnyDatabase",
"dbAdminAnyDatabase",
"readWriteAnyDatabase"
]
}
);
Despite that, when I am in the mongo shell and try to get a list of all users, I get the following error:
use experts_db
switched to db experts_db
> db.getUsers()
2020-01-22T14:30:00.569+0000 E QUERY [js] Error: command usersInfo requires authentication :
_getErrorWithCode#src/mongo/shell/utils.js:25:13
DB.prototype.getUsers#src/mongo/shell/db.js:1763:1
#(shell):1:1
Does anyone know why this happens? I am new to mongo and dont understand how I could fix this

You need to remove the data/db/ volume inside your container then rerun and build again
rm -rf data/db/. # This command should be run from within the container
docker-compose up --build

I have tested the JS script below and it works as expected:
db.createUser(
{
user: "aaa",
pwd: "123",
roles: [ { role: "readAnyDatabase", db: "admin" }, { role: "dbAdminAnyDatabase", db: "admin" }, { role: "userAdminAnyDatabase", db: "admin" }]
});
After the creation, you can hop on mongoDB shell and run db.getUsers() to make sure the user has been successfully created.

Related

Cannot connect to MongoDB outside the docker

I've got the following docker compose file with MongoDB container:
version: '3.6'
services:
mongo:
image: mongo
volumes:
- ./keyfile.txt:/data/keyfile.txt
entrypoint:
- bash
- -c
- |
cp /data/keyfile.txt /data/replica.key
chmod 400 /data/replica.key
chown 999:999 /data/replica.key
exec docker-entrypoint.sh $$#
command: "--bind_ip_all --replSet rs0 --keyFile /data/replica.key"
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
healthcheck:
test: test $$(echo "rs.initiate().ok || rs.status().ok" | mongo -u root -p example --quiet) -eq 1
interval: 10s
retries: 3
network_mode: host
I have to get rid of network_mode: host, so I changed it to
ports:
- "27017:27017"
After that change, I'm not able to connect to the mongo outside of the docker network.
I'm trying to connect to the database using Compass with the following URI:
mongodb://root:example#localhost:27017/?authMechanism=DEFAULT
How to fix that?
This is fully working example.
I'm recommending to create custom DB and custom user instead of using root user.
Use special path of auto-executing queries and create one or multiple databases.
mongodb:
image: mongo:latest
restart: always
ports:
- "27017:27017"
volumes:
- ./var/mongodb:/data/db
- ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: pass
mongo-init.js
db = db.getSiblingDB('SOME_DB');
db.createUser({
user: 'some_db_user',
pwd: '12345',
roles: [{ role: 'readWrite', db: 'SOME_DB' }],
});
db = db.getSiblingDB('SOME_OTHER_DB');
db.createUser({
user: 'some_other_db_user',
pwd: '12345',
roles: [{ role: 'readWrite', db: 'SOME_OTHER_DB' }],
});
db.createCollection('test');

Can i create user, database and collection in mongo Docker?

I'm following the Mongo documentation for create init user with database and collection on first start of container, but when i create user with readWrite permissions i can't access my "dashboard" database with the collection "person_file_upload", with permission denied warning.
I just want to create an non-root user to read and write my database only. Is anything wrong with my script?
version: '3.8'
services:
mongo:
image: mongo:4.4.3-bionic
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: mypassword
MONGO_INITDB_DATABASE: admin
volumes:
- ./proativa-dashboard-mongo/data:/data/db
- ./proativa-dashboard-mongo/init/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
restart: always
ports:
- "127.0.0.1:27017:27017"
networks:
- mongo
container_name: mongo
db.createUser({
user: 'dashboard',
pwd: 'dashboard',
roles: [{
role: 'readWrite',
db: 'admin',
}]
});
db = db.getSiblingDB('dashboard');
db.createCollection('person_file_upload');

mongodb created by Docker-compose, doesn't create initial db?

docker-compose.yml
version: '3.7'
services:
mongodb:
image: mongo:latest
container_name: mongodb
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: devuser
MONGO_INITDB_ROOT_PASSWORD: devuser
MONGO_INITDB_DATABASE: devDB
ports:
- 27017:27017
volumes:
- ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
mongo-init.js
db.createUser(
{
user: "devuser",
pwd: "devuser",
roles: [
{
role: "readWrite",
db: "devDB"
}
]
}
);
use devDB;
db.item.insert(
[
{
"id": "xsd4cv89t5f5um4b",
"name": "r44d7piq",
"price": 1485521573482,
"dateCreation": 1485521569056
}
]
);
I run it
docker-compose up --build -d mongodb
I connect to mongodb
mongo -u devuser -p devuser
I check dbs:
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
Why I don't see the devDB?
It seems to me pretty standard, I've copied the above from several examples...
The database is created on demand when an operation that needs it is performed.
You haven't performed any operations, hence there is no database created.

Connecting using MongoDB Compass to docker mongo image

I'm trying to see the contents of a collection using MongoDB Compass. I have username/password authentication set up. I can log in successfully but can't see any documents in the collection. Instead, I see the error:
An error occurred while loading navigation: command hostInfo requires authentication.
Docker Compose file
version: '3.7'
services:
mongo:
image: mongo
restart: always
ports:
- 27017:27017
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: pass
volumes:
- ./mongo/init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro
- ./mongo:/data/db
mongo-express:
image: mongo-express
restart: always
ports:
- 8081:8081
environment:
ME_CONFIG_BASICAUTH_USERNAME: rmurad93
ME_CONFIG_BASICAUTH_PASSWORD: Qwert111
ME_CONFIG_MONGODB_PORT : 27017
ME_CONFIG_MONGODB_ADMINUSERNAME: admin
ME_CONFIG_MONGODB_ADMINPASSWORD: pass
init-mongo.js file
use admin
db.createUser({
user: "rmurad93",
pwd: "password",
roles: [ { role: "root", db: "admin" } ]
})
Line in terminal mongo compass
mongodb://localhost:27017/rmurad93:password
to connect to MongoCompass you should follow this pattern
mongodb://USERNAME:PASSWORD#localhost:27017/DB_NAME
If you still can't connecting, try using (Fill in connection fields individually)
option shown above instead of (Paste connection string)

How to create an authenticated mongo database in a mongo container with minimal config

I'm using Sails 0.12.3 and mongo 3.2.7
Here's my config/connections.js.
mongo: {
adapter: 'sails-mongo',
host: 'database',
port: 27017,
user: 'user', //optional
password: 'password', //optional
database: 'db' //optional
}
and my docker-compose.yml
version: '2'
services:
myservice:
//blabla
links:
- database
database:
image: 'mongo:latest'
container_name: 'database'
environment:
MONGODB_PASSWORD: "password"
MONGODB_USER: "user"
MONGODB_DATABASE: "db"
The problem comes whenever I build the containers with docker-compose up --build, the error comes from the sails-mongo module.
error: A hook (`orm`) failed to load!
error: Error: Failed to connect to MongoDB. Are you sure your configured Mongo instance is running?
Error details:
{ MongoError: Authentication failed.
at Function.MongoError.create (/app/node_modules/mongodb-core/lib/error.js:31:11)
at commandCallback (/app/node_modules/mongodb-core/lib/topologies/server.js:929:66)
at Callbacks.emit (/app/node_modules/mongodb-core/lib/topologies/server.js:116:3)
at .messageHandler (/app/node_modules/mongodb-core/lib/topologies/server.js:282:23)
at Socket.<anonymous> (/app/node_modules/mongodb-core/lib/connection/connection.js:273:22)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at readableAddChunk (_stream_readable.js:172:18)
at Socket.Readable.push (_stream_readable.js:130:10)
at TCP.onread (net.js:542:20)
name: 'MongoError',
message: 'Authentication failed.',
ok: 0,
code: 18,
errmsg: 'Authentication failed.' }
Is there any extra configuration I need to just run the containers? I understand that Mongo doesn't create a database unless there's some data to store but I'm not sure if this is related at all.
First lets address your problem: Authentication failed. sails-mongo cannot connect to mongodb. Why is that? I see that you provided some environment variables to the mongodb docker container:
environment:
MONGODB_PASSWORD: "password"
MONGODB_USER: "user"
MONGODB_DATABASE: "db"
However this is not documented in https://hub.docker.com/_/mongo/. The mongodb container is ignoring this values, thus no authentication is configured. sails-mongo will try to authenticate, however this fails because no such user exists. You can test it by simply commenting out user and password in config/connections.js. Your service will be able to connect.
In https://hub.docker.com/_/mongo/ it is documented how you enable authentication:
docker run --name some-mongo -d mongo --auth
Adding user:
$ docker exec -it some-mongo mongo admin
connecting to: admin
> db.createUser({ user: 'jsmith', pwd: 'some-initial-password', roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] });
Successfully added user: {
"user" : "jsmith",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
To automate this you could put the user creation in a shell script and trigger it in docker compose.
There is another solution that you can apply. First ask yourself, why do you need authentication at all? Do you want to access the mongodb instance from any ip address? Then you need authentication. If not you might leave authentication disabled. If mongodb binds to localhost, nobody outside of localhost will be able to connect to it.
With docker you can harden this even further: any access to the mongodb instance is forbidden. Only containers that are on the same network as mongodb may connect.
Using docker-compose version 2 network feature:
version: "2"
services:
my-app:
image: myHubRepo/my-app:v1.X.Y
container_name: my-app
environment:
- MONGODB=mongodb:27017
- APP_PORT=80
- STAGE=production
expose:
- "80"
networks:
- back-tier
restart: always
mongodb:
image: mongo
volumes:
- mongodb-data:/data/db
networks:
- back-tier
restart: always
volumes:
mongodb-data:
driver: local
networks:
back-tier:
Mongodb is not accessible from outside of its very own container despite from containers that are on the same network back-tier.
Adjust env/production.js accordingly:
module.exports = {
connections: {
prodMongoDb: {
adapter: 'sails-mongo',
url: 'mongodb://' + process.env.MONGODB + '/my_app'
}
},
models: {
connection: 'prodMongoDb'
},
port: process.env.APP_PORT || 8080,
log: {
level: "warn"
}
};
For more information on networks with compose: https://docs.docker.com/compose/networking/