This blog post explains how to install and run a local development install of MongoDB. It also covers how to enable authentication, which sadly isn’t enabled by default. It describes how to install a distro neutral non-packaged version of MongoDB where you download a tarball and run it from a separate directory.

The upstream MongoDB project also offers packaged versions for various distros, for example the guide at Ubuntu helps you drop repo.mongodb.org/apt into sources.list.d etc so that sudo service mongod start works and the mongod configuration file lives in /etc/mongod.conf. Finally, you can of course also install the mongodb package from Debian/Ubuntu universe (or similar on other distros) but then you’re likely not getting the latest version so it’s a good idea to read up on what you’re missing (for example, some earlier MongoDB versions had per-collection locking instead of per-document locking).

Note that this post only covers a basic local development installation, for real deployments you most likely need sharding and TLS etc.

Step 1: Fetch the right tarball from mongodb.com

Download the right version of the MongoDB tarball. Unpack it (to ~/opt or /opt or wherever you usually put non-package software) and then try running ./bin/mongod --help to see that it properly finds the dynamically linked OpenSSL.

For example, the Amazon Linux version of MongoDB has OpenSSL linked to the specific version that ships on the Amazon Linux AMI, so if you spawn an Ubuntu AMI on AWS and try to run the Amazon Linux AMI you’d get an error like:

/usr/lib/libcrypto.so.10: version `libcrypto.so.10' not found (required by ./mongod)
/usr/lib/libssl.so.10: version `libssl.so.10' not found (required by ./mongod)

Step 2: Create and chmod a data directory

By default MongoDB stores data in /data/db but you can use another data directory by passing a --dbpath ~/mongo-data or similar argument to mongod. In both cases the data directory should be chmod’ed so that it is readable by the user account that will run mongod (and most likely readable only by that account as well, depending on your preferences). You should definitely not run mongod as root.

Step 3: Use ––bind_ip to safely enable authentication

When you start mongod it will, by default, listen on all local IP addresses (all interfaces, not just localhost!) and it will run with no authentication enabled (needless to say, this is a pretty dangerous default). For example, if you just spawned a Digital Ocean droplet with a pristine Ubuntu installation, there won’t be a firewall active and the whole internet can freely login and create database administrator accounts for themselves on your MongoDB server. For AWS, there might be a security group that blocks inbound traffic on ports other than 22 (or whatever has been explicitly opened) but it’s a good habit to always launch with --bind_ip 127.0.0.1 the first time you launch mongod (i.e. before you’ve enabled authentication). Also in many cases, like local development installations, you can and should continue to run with --bind_ip 127.0.0.1 even after authentication is enabled.

To enable authentication:

  • Start MongoDB using ./bin/mongod --dbpath ~/mongo-data --bind_ip 127.0.0.1
  • Create an administrator user called bofh with password fu, by running:
use admin
db.createUser({user:"bofh", pwd:"fu", roles:[{role:"root", db:"admin"}]})
  • Finally, restart mongod with the --auth command line argument.

Of course, at this point you might want to both enable authentication and also set the bind IP in a config file instead of passing a bunch of command line arguments on every launch.

Step 4: Verify that the account works

You should now be able to login to the above account using:

./mongo -u SOME_USERNAME -p --authenticationDatabase admin

This will prompt you for the password interactively. Technically, mongo shell allows you to pass the password itself as an argument (i.e. -p SOME_PASSWORD) but this should be avoided because you don’t want all your passwords stored in ~/.bash_history where they could leak via a sloppy umask or backup job.

Step 5: Optionally create auxiliary lower privilege accounts

If you have some reporting / statistics gathering utility that can run with read only access to a particular database you can create a separate account with such rights by logging in as an administrator and then running:

use admin
db.createUser({user:"ro", pwd:"123", roles:[{role:"read", db:"someDatabase"}]})