Skip to content

MongoDB Setup for Production

Adrian Matei edited this page Jun 1, 2020 · 8 revisions

This wiki page presents how MongoDB (v3.2) is configured in production on Ubuntu 16.04 Xenial to support www.bookmarks.dev

Add the MongoDB Repository

Because the Ubuntu repositories don’t contain a current version, we’ll need to use the MongoDB repository.

  1. Import the MongoDB public GPG key for package signing

The Ubuntu package management tools (i.e. dpkg and apt) ensure package consistency and authenticity by requiring that distributors sign packages with GPG keys. Issue the following command to import the MongoDB public GPG Key

$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927
  1. Create a list for MongoDB

Add the MongoDB repository to your sources.list.d directory:

$ echo "deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list
  1. Update your repositories. This allows apt to read from the newly added MongoDB repo:
$ sudo apt-get update

Install MongoDB

Now that the MongoDB repository has been added, we’re ready to install the latest stable version (at that time was 3.2) of MongoDB:

$ sudo apt-get install mongodb-org

This command installs mongodb-org, a meta-package that includes the following:

  • mongodb-org-server - The standard MongoDB daemon, and relevant init scripts and configurations
  • mongodb-org-mongos - The MongoDB Shard daemon
  • mongodb-org-shell - The MongoDB shell, used to interact with MongoDB via the command line
  • mongodb-org-tools - Contains a few basic tools to restore, import, and export data, as well as a variety of other functions.

These packages provide a good base that will serve most use cases, and we recommend installing them all. However, if you want a more minimal installation, you can selectively install packages from the above list rather than using the mongodb-org metapackage.

For more information on the installation process and options, refer to the official MongoDB installation tutorial.

Run MongoDB community edition

To start, restart, or stop the MongoDB service, issue the appropriate command from the following:

$ sudo systemctl start mongod
$ sudo systemctl restart mongod
$ sudo systemctl stop mongod

You can also enable MongoDB to start on boot:

$ sudo systemctl enable mongod

Configure MongoDB

The configuration file for MongoDB is located at /etc/mongod.conf, and is written in YAML format. Most of the settings are well commented within the file. We’ve outlined the default options below:

  • dbPath indicates where the database files will be stored (/var/lib/mongodb by default)
  • systemLog specifies the various logging options, explained below:
    • destination tells MongoDB whether to store the log output as a file or syslog
    • logAppend specifies whether to append new entries to the end of an existing log when the daemon restarts (as opposed to creating a backup and starting a new log upon restarting)
    • path tells the daemon where to send its logging information (/var/log/mongodb/mongod.log by default)
  • net specifies the various network options, explained below:
    • port is the port on which the MongoDB daemon will run
    • bindIP specifies the IP addresses MongoDB to which binds, so it can listen for connections from other applications

We strongly recommend uncommenting the security section and adding the following:

File excerpt: /etc/mongod.conf

security:
  authorization: enabled

The authorization option enables role-based access control for your databases. If no value is specified, any user will have the ability to modify any database. We’ll explain how to create database users and set their permissions later in this guide.

For more information on how to customize these and other values in your configuration file, refer to the official MongoDB configuration tutorial.

After making changes to the MongoDB configuration file, restart the service as shown above.

Create database and users

User Administrator

With access control enabled, we need to ensure we have a user with userAdmin or userAdminAnyDatabase role in the admin database. This user can administrate user and roles such as: create users, grant or revoke roles from users, and create or modify customs roles.

You can create users either before or after enabling access control. If you enable access control before creating any user, MongoDB provides a localhost exception which allows you to create a user administrator in the admin database. Once created, you must authenticate as the user administrator to create additional users as needed.

Ok, so let's create the admin user.

  1. Connect to the mongo shell
$ mongo
  1. Create the user administrator

In the admin database, add a user with the userAdminAnyDatabase role. In the following excerpt we create the user mongo-admin in the admin database:

> use admin
switched to db admin

> db.createUser(
   {
     user: "mongo-admin",
     pwd: "abc123",
     roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
   }
 )

Successfully added user: {
	"user" : "mongo-admin",
	"roles" : [
		{
			"role" : "userAdminAnyDatabase",
			"db" : "admin"
		}
	]
}

Find the real password in the KeePass Database

  1. Re-start the MongoDB instance with access control.

Re-start the mongod instance with the --auth command line option or, if using a configuration file, the security.authorization setting.

$ mongod --auth --port 27017 --dbpath /data/db1

Clients that connect to this instance must now authenticate themselves as a MongoDB user. Clients can only perform actions as determined by their assigned roles.

  1. Connect and authenticate as the user administrator

Using the mongo shell, you can:

  • Connect with authentication by passing in user credentials, or
  • Connect first withouth authentication, and then issue the db.auth() method to authenticate.

To authenticate during connection

Start a mongo shell with the -u <username>, -p <password>, and the --authenticationDatabase <database> command line options:

$ mongo --port 27017 -u "mongo-admin" -p "abc123" --authenticationDatabase "admin"

To authenticate after connecting

Connect the mongo shell to the mongod:

$ mongo --port 27017

Switch to the authentication database (in this case, admin), and use db.auth(<username>, <pwd>) method to authenticate:

> use admin
> db.auth("mongo-admin", "abc123" )

The mongo-admin user created in Step 2 is purely administrative based on the roles specified. It is defined as an administrator of user for all databases, but does not have any database permissions itself. You may use it to create additional users and define their roles. If you are using multiple applications with MongoDB, set up different users with custom permissions for their corresponding databases.

Create codingpedia-bookmarks database

To create a new database, we login as mongo-admin as shown previously, then use the use command:

> use codingpedia-bookmarks
switched to codingpedia-bookmarks

Create codingpedia user

Use the createUsercommand as follows:

db.createUser(
  {
    user: "codingpedia",
    pwd: "xyz123",
    roles: [
      { role: "readWrite", db: "codingpedia-bookmarks" }
    ]
  }
)

Show current user

The connectionStatus command shows authenticated users (if any, among some other data):

> db.runCommand({connectionStatus : 1})

Which results in something like bellow:

{
	"authInfo" : {
		"authenticatedUsers" : [
			{
				"user" : "mongo-admin",
				"db" : "admin"
			}
		],
		"authenticatedUserRoles" : [
			{
				"role" : "userAdminAnyDatabase",
				"db" : "admin"
			}
		]
	},
	"ok" : 1
}

So if you are connecting from the shell, this is basically the current user

You can also add the user name to prompt by overriding the prompt function in .mongorc.js file, under OS user home directory ($ vim ~/.mongorc.js). Roughly:

prompt = function() {
    user = db.runCommand({connectionStatus : 1}).authInfo.authenticatedUsers[0];
    if (user) {
        return   user.user + "> ";
    }
    return "> ";
}

Then after connection:

$ mongo -u mongo-admin -p --authenticationDatabase admin
MongoDB shell version: 3.2.11
Enter password:
connecting to: test
mongo-admin>

see in the last line, the current user is displayed. Thank you Ori Dar for this solution.

This does not work however if you change the user via `db.auth("user", "userPwd")``, once logged in...

Show all users

Use the show users command to print a list of users for the current database:

> use codingpedia-bookmarks
> show users
{
	"_id" : "codingpedia-bookmarks.codingpedia",
	"user" : "codingpedia",
	"db" : "codingpedia-bookmarks",
	"roles" : [		
		{
			"role" : "readWrite",
			"db" : "codingpedia-bookmarks"
		}
	]
}

For more information on access control and user management, as well as other tips on securing your databases, refer to the MongoDB Security Documentation.

This concludes our wiki page. We can now confidently persist the codingmarks in MongoDB, and connect to it via our back-end.