How to setup user authentication in MongoDB 3.0
MongoDB Authentication example
Docker now supports adding host mappings
A sample Docker workflow with Nginx, Node.js and Redis
Setting up a Replicated MongoDB using Authentication in Docker on DigitalOcean
$ docker run --name mongo -v "$PWD"/mongo/data:/data/db -p 27017:27017 -d mongo- First we need to connect to the database from another mongo container
$ docker run -it --link mongo:mongo --rm mongo sh -c 'exec mongo "mongo:27017/test"'- Adding users When you're connected to the MongoDB you're going to want to switch to the Admin database, using,
$ use adminNow we can add users. Create a new site admin user called siteUserAdmin,
$ db.createUser ({
user: "siteUserAdmin",
pwd: "siteUserAdmin",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
});and a Root User called siteRootAdmin,
$ db.createUser ({
user: "siteRootAdmin",
pwd: "siteRootAdmin",
roles: [ { role: "root", db: "admin" } ]
});Now exit the mongo-container with the apply named command exit
- Stop the mongo again, and remove it
$ docker stop mongo
$ docker rm -f mongoTo start database again and enable authentication let add --auth flag in command,
$ docker run --name mongo -v "$PWD"/mongo/data:/data/db -p 27017:27017 -d mongo --authWe need connect again to mongo database with command in previous section and connect to hitdb,
$ use hitdbLet's create user for hitdb ,
$ db.createUser ({
user: "hitdbadmin",
pwd: "hitdbadmin",
roles: [ { role: "root", db: "admin" } ]
});Now, the hitdb is already to using for node.js application.
We will create an simple application with only one feature which there are request (GET method) from client, application will count up one and save result into hitdb (this database is created in previous section).
Let start by installing Express.js,
$ npm install expressand Mongodb driver,
$ npm isntall mongodbLet's create file src/app.js and input code such as,
'use strict';
const app = require ('express') ();
module.exports = function createApp (db) {
app.get ('/hit', (req, res) => {
let collection = db.collection ('hitcollection');
collection.findOne ({name:'hit'})
.then ((doc) => {
if (doc) {
collection.updateOne ({name:'hit'},{$set: {count: doc.count + 1}})
.then ((docUpdate) => {
res.status (200).send (`Hit ${doc.count+1}`);
})
.catch ((error) => {
res.status (500).send ('Server error');
});
} else {
collection.insertOne ({name:'hit', count: 1})
.then ((docCreated) => {
res.status (201).send ('Hit 1');
})
.catch ((error) => {
res.status (500).send ('Server error');
});
}
})
.catch ((error) => {
res.status (500).send ('Server error');
});
});
return app;
}This code is simple creating an Express.js app with parameter is mongodb (db). You can understand code will do,
- Try to finding in database document with name
hitin collection with namehitcollection - If
hitdocument is exist, let update count up to one and save again to database. - If
hitdocument is not exist, let create new one and save to database with count is1.
Next, we create src/index.js to connecting to hitdb database and start express application, let's input code such as,
'use strict';
const app = require ('./app');
const mongodb = require ('mongodb');
let MongoClient = mongodb.MongoClient;
const mongoUrl = 'mongodb://hitdbadmin:hitdbadmin@mongo:27017/hitdb';
const port = process.env.PORT | 3000;
MongoClient.connect (mongoUrl, (error, db) => {
if (error) return console.error ('Cannot connect to MongoDB. Error', error);
console.log ('Connect to MongoDB successful!');
app(db).listen (port, () => console.log ('Application listen at ' + port));
});This code start connection to mongodb with Mongodb driver and Url mongodb://hitdbadmin:hitdbadmin@mongo:27017/hitdb with,
hitdbadmin:hitdbadminis user and password ofhitdbmongo:27017is address of mongo in docker
Note: If mongo is installed same machine or test with current mongo in docker, you can use
localhost:27017or127.0.0.1:27017
Now, start the nodejs application you will see,
$ node src/index.js
Connect to MongoDB successful!
Application listen at 3000Let's count up hit with curl in terminal
$ curl localhost:3000/hit
Hit 1% $ curl localhost:3000/hit
Hit 2% Yeah, nodejs application is done. Let's dockerize application with Dockerfile such as,
# Start with base image from official
FROM node:6.9.2-alpine
MAINTAINER duytran
# Change workdir
WORKDIR /app
# Add current src and install file
ADD src src
ADD package.json package.json
# Run update and install package for application
RUN npm update
# Start application
CMD node src/index.jsAnd build it with command,
$ docker build -t node-hit .Start nodejs application docker,
$ docker run -d --name node-app --link mongo:mongo -p 3000:3000 node-hitTo make sure, node application start successful, type command,
$ docker logs node-app
Connect to MongoDB successful!
Application listen at 3000Ok, Everything done. Let's move to next secion.
We need pull Nginx image from DockerHub. Execute the following bash command to do just that:
$ docker pull nginx:latestWe'll be using a custom nginx/nginx.conf file that will be mapped to the containers /etc/nginx directory. Here is the server portion whichs defines the proxy to the node.js server
...
server {
listen 80;
index index.html;
server_name localhost;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/public;
location ~* /hit {
proxy_pass http://node-app:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
The configuration will proxy requests to the url /hit to the Node.js Docker container! Note the proxy_pass entry, uses the name of the Node.js Docker container, node-app, that was created.
To create the Nginx container execute the following bash command from the project root directory:
$ docker run -d --name web -p 8080:80 -v $(pwd)/web/src:/var/www -v $(pwd)/nginx/nginx.conf:/etc/nginx/nginx.conf --link node-app:node-app nginxConfirm the Nginx Docker container is running by executing the following bash command:
$ docker psYou should see a running container with the name web.
Point your browser to http://localhost:8080. CLick on the link labled HIT and that will take you to the nodejs server! Notice the link does not contain the port 3000. This is because Nginx is configured to use the /hit url as a proxy to the nodejs server.
Full source code for this example docker-node-mongo-nginx