Community Post

Getting Started with MongoDB on Linux

Quite recently, I decided to jump ship to Mongodb after years of web development using MySQL database. The one thing that attracted me the most to Mongodb is that you can start pushing data to the database without first defining a schema. This means you can spend more time iterating app code without lifting a finger managing the database schema.

Mongodb is a very mature platform with about 10 years in development and is being used by big name companies that handle data for millions of customers everyday. It has a huge community behind it and is currently ranked fourth as the most popular database.

This post is an extended getting start guide for Ubuntu & Linux Mint users on how to properly set up a secure Mongodb server and how to solve common configuration issues. The information provided here is as a result of knowledge gained through researching the official doc guides and experimenting to validate the concepts learned.

Table of Contents

    I've provided this knowledge here to make it easy for beginners to transition to the Mongo database on the Linux platform.

    1) Installing Mongodb

    Before installing Mongodb, make sure you have purged all previous versions of mongodb. The mongodb version that is currently available in the official ubuntu repositories is outdated and has an issue where large amounts of disk space are consumed by its journal. To purge the outdated version, just execute the following:

    sudo apt-get purge mongo*
    sudo rm -R /var/lib/mongo

    Next, you'll need to add the official mongodb repository that contains the latest community version.

    sudo apt-key adv --keyserver hkp:// --recv 0C49F3730359A14518585931BC711F9BA15703C6
    # For Ubuntu Xenial or Linux Mint 18.*
    echo "deb [ arch=amd64,arm64 ] xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list
    # For Ubuntu Trusty or Linux Mint 17.*
    echo "deb [ arch=amd64  or Linux Mint 17] trusty/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list
    # For Ubuntu Precise or Linux Mint 13
    echo "deb [ arch=amd64 ] precise/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list
    sudo apt-get update

    Once the repository cache is updated, run the install command:

    sudo apt-get install -y mongodb-org

    Ensure you typed mongodb-org, and not mongodb, otherwise you'll install the old version.

    2) Auto-starting Mongodb Service

    The next obvious step after finishing installation is to start the mongo shell, right?

    Mongo shell

    Unfortunately, you will encounter connection errors. This is because Mongodb does not start automatically on boot or after installation. To fix this, run the following commands that will start the mongodb service and enable it to auto-start on boot.

    sudo systemctl start mongod
    sudo systemctl enable mongod

    To confirm that mongodb server has successfully started, execute either of the following commands:

    # Check ports in use
    netstat -plntu | grep 27017
    // Check service status
    sudo service mongod status

    27017 is the default port used by Mongodb server to listen for connections. I prefer the second command for checking status as it displays more information such as if its enabled to run on boot and if there are errors in its configuration file if they are any.

    3) Basic Performance Tuning

    Now that the Mongodb service is running, you can now use mongo shell to access the server by executing mongo in the terminal.

    Mongo shell warnings

    The mongo shell starts successfully, however, you get hit by several warning messages. Despite the warnings, you can create new databases and add documents to the collections. However, I recommend that we first resolve the warning messages.

    Let's start with these warning messages that are in regards to performance:

    ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
    **        We suggest setting it to 'never'
    ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
     **        We suggest setting it to 'never'

    According to the official docs, Mongo recommends that you disable a Linux Memory Management feature called Transparent Huge Pages as it causes databases workloads to perform poorly.

    To fix this, create a new file at /etc/init.d/disable-transparent-hugepages and paste this content. After saving the file, execute the following commands:

    sudo chmod 755 /etc/init.d/disable-transparent-hugepages
    sudo update-rc.d disable-transparent-hugepages defaults

    Since the above commands affect the Linux kernel, you'll have to restart the entire machine for the changes to take effect.

    After restarting the machine, simply type mongo and you should connect to the mongodb server. The shell no longer displays the warning messages regarding the 'transparent-hugepages.

    However, there are two more warnings that still need to be solved which we shall look at in the next step.

    4) Basic Mongodb Security

    By default, mongodb is insecure. The reason for this, I believe, is to make it easy for new users to try out Mongodb comfortably, and hence increase adoption. Security is left at the hands of the users to implement when they are ready.

    When you access the mongo shell like this...

    mongo get logged in as default user. In this account you are free to perform any CRUD operation you feel like provided authentication hasn't been set up. Lets try some basic commands in the mongo shell to confirm this:

    // switch to a new database
    use twist
    // insert a document to a new collection called 'users'
    db.users.insert({name:"mike", email:""})
    // list all documents in the newly created collection

    All the above operations should execute with no problem whatsoever. Now lets proceed with securing our mongodb server in order to protect our data from anonymous users.

    First, we need to turn on the 'auth' setting for mongodb. There are several ways of doing it, but the method I prefer is by editing the /etc/mongod.conf file.

    Using administrative privileges, edit the file /etc/mongod.conf using your favorite text editor:

    # using console editor
    sudo nano /etc/mongod.conf
    # using Ubuntu text editor
    sudo pluma /etc/mongod.conf
    # using Linux Mint text editor
    sudo xed /etc/mongod.conf

    Look for the commented out section called security and edit as follows:

        authorization: enabled

    Save the changes above, close the file and restart mongodb service for the changes to take effect.

    # restart mongodb server
    sudo service mongod restart
    # confirm mongodb service is running
    sudo service mongod status
    # log in as default user

    You'll notice that the remaining warning messages have now disappeared. Mongodb is now running in auth mode, therefore the 'access control' warning should disappear. The 'XFS file system' warning too also disappears mysteriously after enabling authentication. Currently, I don't know why this happens. However, I'll be sure to use XFS file system when installing Mongodb in production servers since it comes highly recommended.

    Let's now confirm that default users can't read or write to any database. Inside the mongo shell, execute the following:

    use twist
    db.users.insert({name:"maggie", email:""})

    As expected, the default user is prevented from accessing documents from any collection. Now we can proceed with creating an authenticated user.

    The way authentication works in Mongodb is that you need to save user accounts in a special database called admin. Within this database you will need to create an admin user who will be responsible for creating new user accounts and assigning roles.

    As an admin user, you can create more users within the admin database, or you can switch to a new database and create them there. However, during login authentication, you will have to specify which database is holding the user credentials you want to login.

    As demonstrated earlier, the default user currently has no privileges. However, since no users have been created, an exemption will be made to allow the default user to create an admin user.

    // switch to the admin database
    use admin
    // create a new user to be stored in the admin database
            { role: "userAdminAnyDatabase", db: "admin"  }
    // log out of mongo shell

    After the admin user has been created, the default user account won't be allowed again to create any user.

    To log in as the admin user, do...

    mongo -u admin --authenticationDatabase admin -p

    ... you will be prompted to enter the password for the newly created admin user. The flag --authenticationDatabase is used to pass the name of the database holding user credentials.

    As the new mongodb admin, you can now create new users for other databases. Let's create one for the database twist:

    // ensure the new user is created under admin
    use admin
    // create new user and assign Read/Write permission only
        roles:[{ role: "readWrite", db: "twist"  }]  

    Exit the mongo shell and now login back with the new user credentials within the shell.

     mongo -u twister --authenticationDatabase admin -p

    Enter the password as prompted. Next, switch to the twist database and add some data.

    // switch to the twist database
    use twist
    // display all collections
    show collections
    // insert a new record
    db.users.insert({name:"maggie", email:""})
    // display all records

    As expected you now have access to read and write capability in the twist database. As a simple exercise, try switching to another database, say library and try adding documents and see what happens.

    As expected you will get authorization errors informing you that you lack the permission to perform the operation.

    If you would like to update a user account, say change password, you normally have to logout and login as the admin user to be able to do that. Alternatively, you can do this while still logged in as another user:

    // Switch to the admin database
    use admin
    // Login as the admin user
    // Change the user password
            pwd: "zyx123"

    You will need to exit the mongo shell in order for the password change to take effect. You can now log in back again using either mongo shell parameters or log in as default user then use db.auth() function to login as 'twister'. When using db.auth() function, make sure you switch to the admin database first since this is where the user accounts are stored. When it returns '1', it means you are authenticated and you can now switch to the twist database to perform some data manipulation.

    So far you have learned how to secure your Mongodb server. You can go over the official security checklist if you want to further enhance your database security.

    5) Mongo CRUD Operations

    So far, I have shown you how to insert data. Here are other common operations that you need to learn.

    Insert Documents

    Lets first create a new collection with data that we shall manipulate with using other operations. But before we get started, here are some naming conventions suggested for Mongodb collections:

    • Use lower case names
    • Use plural
    • Avoid word separators such as '-' or '_'
    • Use dot notation to indicate relation e.g.
      • users
      • users.pagevisits

    Lets now create a collection called pets and populate it with data. Below you will see the different ways of inserting data into a collection.

    // Insert single document
    db.pets.insert({name:"Fluffy", owner:"Harold", speices:"cat", sex:"F",birth:"2013-02-04"})
    // insertOne() returns the object id
    db.pets.insertOne({name:"Claws", owner:"Gwen", speices:"cat", sex:"M",birth:"2014-03-17"})
    // Insert an array of documents
        {name:"Buffy", owner:"Harold", speices:"dog", sex:"F",birth:"2009-05-13"},
        {name:"Fang", owner:"Benny", speices:"dog", sex:"M",birth:"2010-08-27"},
        {name:"Bowser", owner:"Diane", speices:"dog", sex:"M",birth:"2014-08-31"}
    // insertMany() returns array of objectIds
        {name:"Chirpy", owner:"Gwen", speices:"bird", sex:"F",birth:"2009-09-11"},
        {name:"Whistler", owner:"Gwen", speices:"bird", sex:"M",birth:"2007-12-09"},
        {name:"Slim", owner:"Benny", speices:"snake", sex:"M",birth:"2016-04-29"}
    // display all rows
    // returns number of rows (should be 8 if you executed all of the above)


    Executing queries in mongodb is fairly simple. If you are familiar with SQL, then you'll understand the following operations.

    // list all documents a.k.a select * from pets
    // list all pets owned by Gwen
    // lists all male pets
    // list all male dogs
    db.pets.find({sex:"M", speices:"dog"})
    // list pets that are either female cats or birds
        $or: [ 
            {speices:"cat", sex:"F"}, 
    } )
    // list all pets born on the year 2010 and later
        birth: { $gt:"2010-01-01" } 

    Update Documents

    Now that there is some data to manipulate, lets do an update operation

        { name: "Slim"},
            $set: { owner: "Ben", speices:"Lizard"}
    // display all rows

    In the above update() function, I have provided 2 parameters

    • filter (similar to WHERE clause)
    • update data

    You can also provide a third parameter called options. Examples of options are:

    • { multi:true } allows update operation to affect more than one matching rows
    • { upsert:true} if the filter specified doesn't match a document, a new document is created

    There are more variations of the update() function you can have a look at them here

    Remove Documents

    Let's first create a new collection for demonstration

    db.jets.insert({name:"Lockheed Martin F-22"})

    The remove() function, just like the SQL 'DELETE' command, is a dangerous function that should be handled with care. Simply executing something like this...


    ... will delete all documents in a collection. Once a document is deleted, it doesn't go to trash, it goes away forever. There is no undo operation or rollback function you can use to recover the deleted data. If you did this accidentally on a production database, the ramifications can be pretty serious. This happened at work to a colleague of mine. Luckily he was able to restore the data from the daily backups.

    However, if you really wanted to delete all documents from a collection, this is the recommended way

    // display all collections first
    show collections
    // drop jets collection
    // display all collections again
    show collections

    By using drop() function, the indexes get deleted too and completely gets rid of the collection. Using just remove({}) will just delete the documents and retain the indexes, hence the collection will still exist despite not containing any data.

    Now , let's delete a single document from the pets collection

    // Lets display all pets
    // Delete one document
    // Confirm the specified document has been deleted

    The remove() function works as expected, however, its still risky as it will delete all documents matching the filter. A better way is to use the deleteOne() function and pass it the _id value of a document. This way you will be 100% sure that you are deleting the correct document.

    // Display the pets again and copy an object id
    // Delete one document
    // Confirm it has been deleted

    6) Administration GUI

    Mongodb doesn't come packaged with a GUI administration interface, however there are plenty of third-party GUI interfaces available. Some are commercial, and some are open-source. They are all listed on the Mongo docs site. They don't all provide the same features, you may have to dig a bit deeper to determine if the tool meets your project requirements.

    I can't say for sure which is the most popular Mongo GUI tool available, but I have found that RoboMongo and Studio-3T(formerly MongoChef) seem to be the most popular. Personally, I would recommend Studio-3T as it does appear to provide all features available in RoboMongo plus a lot more including user administration. Studio-3T also comes in three flavours, you can view the comparison here.

    For this guide I'll just show you how to install Studio-3T. Head over to the site and click the Download for Linux button. After download is complete, use the extraction tool to uncompress it in your Downloads folder.

    Uncompress Studio-3T

    Open your terminal and navigate to your downloads folder. Move the robomongo folder to the /opt folder. You'll probably need root permission to do that.

    # move studio-3t to /opt folder
    sudo mv studio-3t-5.0.1-linux-x64/ /opt/studio3t/
    # download icon
    cd /opt/studio-3t
    sudo wget
    # make studio-3t executable available in PATH
    cd /usr/bin
    sudo ln -s /opt/studio3t/bin/ studio3t

    Let's create a menu entry for Studio-3T using the menu editor. Just place your mouse cursor over the your Desktop Menu and right-click, select Edit Menus. Then select Programming. Click on new item and enter the path to Studio-3t executable. Also select the icon that we downloaded in the /opt/studio3t folder.

    Studio-3T Menu Entry

    Now that we have finished installing, lets start the application. You can either start it from the menu or in the terminal. Once the app starts, you will be given three options. You can choose either the free version or the 14 day pro trial.

    After you have chosen you will be provided with the connection dialogue.

    Studio-3T Connection Dialogue

    Let's first create a connection for the admin user, then the twister user. Click New Connection, specify 'Admin' as the name of connection. Make sure sure connection type is set to 'Direct Connection'. Click the Authentication Tab, under mode select Basic, then provide the admin credentials. For the authentication DB, set it to 'admin'. Click save to close the dialogue.

    Studio-3T New Connection

    To create a connection for the user 'twister', just repeat the same steps. The authentication DB will remain 'admin'. When you connect as a certain user, Studio-3T will only show you databases that you have access to. After you have saved the new connection, you can go ahead and connect to both 'Admin' and 'Twist'.

    Studio-3T Interface

    As you can see, the Admin user can see all the databases but the Twist user can only see admin & twist database. Although the Admin user can see twist database, the collections are not accessible. Let's see if we can correct this.

    Right click on the admin database under Admin connection, then choose manage users. Select the admin user, then click on Grant Roles Button. Choose 'readWriteAnyDatabase' then click Grant.

    Studio-3T Grant Roles

    Right click on th Admin connection and select Refresh All. Now under the Admin connection, access pets data.

    Studio-3T View Collection

    Studio 3T has quite a list of features that are beyond the scope of this guide. I'll leave you to it exploring both Mongodb and the Studio 3T tool.


    I hope you have enjoyed learning how to setup and configure a secure Mongodb database. You have simply scratched the surface of the many possibilities and great projects you can come up with this awesome database platform. Despite what you have learned today, you will still need to do a bit more research on how to become an effective Mongodb user.

    Michael Wanyoike

    2 posts

    I like keeping it simple. I write clean, readable and modular code. I love learning new technologies that bring efficiencies and increased productivity to my workflow. Currently am into React & Javascript stuff.