Compose Database-as-a-Service Help and Documentation

Everything you need to know about Compose, Hosted or Enterprise, is here in our help system. Whether you run one database for your businesses' sole application or six different databases to support an entire corporation, we've got the information you need.

Connecting to MongoDB

Connections to MongoDB on Compose are available with, and without, SSL enabled. This is set on a deployment-wide basis and, for your own and your clients security, we recommend you run your deployments with SSL enabled.

Command line SSL

The command line shell mongo can fail with errors like:

$  mongo example.dblayer.com:10373/admin -u user -p pass
MongoDB shell version: 3.0.4
connecting to: example.dblayer.com:10373/admin
2015-06-23T10:19:48.866+0100 I NETWORK  DBClientCursor::init call() failed
2015-06-23T10:19:48.868+0100 E QUERY    Error: DBClientBase::findN: transport error: example.dblayer.com:10373/admin ns: admin.$cmd query: { whatsmyuri: 1 }
    at connect (src/mongo/shell/mongo.js:181:14)
    at (connect):1:6 at src/mongo/shell/mongo.js:181
exception: connect failed

This, or similar errors, are often caused by using a non-SSL enabled mongo to connect to the SSL-enabled MongoDB on Compose. First check if you have SSL enabled mongo tools installed locally. One way to do this is to run mongo --help | grep ssl:

$ mongo --help | grep "ssl"                                                  
  --ssl                               use SSL for all connections
  --sslCAFile arg                     Certificate Authority file for SSL
  --sslPEMKeyFile arg                 PEM certificate/key file for SSL
  --sslPEMKeyPassword arg             password for key in PEM file for SSL
  --sslCRLFile arg                    Certificate Revocation List file for SSL
  --sslAllowInvalidHostnames          allow connections to servers with 
  --sslAllowInvalidCertificates       allow connections to servers with invalid
  --sslFIPSMode                       activate FIPS 140-2 mode at startup
$

If you don't see this response, you need to update your locally installed mongo to include SSL. Current downloads for Windows and Linux MongoDB include SSL support. For Mac OS X, SSL is not compiled in by default. We recommend for Mac OS X, that you install Homebrew and the required Xcode tools, then run brew install mongodb --with-openssl which will compile a MongoDB with SSL enabled and install it for you. If you already installed with Homebrew, remember to run brew uninstall --force mongodb to uninstall the old version before running that.

Once you have an SSL enabled mongo installed, you will need to run it with the --ssl flag and one of the two required flags that go with it --sslAllowInvalidCertificates or --sslCAFile. The --sslAllowInvalidCertificates flag is simplest to use, as it tells the SSL to not verify the certificates being used to encrypt the connection:

$ mongo -ssl -sslAllowInvalidCertificates example.dblayer.com:10373/admin -u user -p pass

For the --sslCAFile option, we need to have the SSL certificate file for the server. You'll find this on the Compose console for your MongoDB; it's revealed by clicking Show SSL Public Key*. You'll want to copy and paste all the text, from -----BEGIN to END CERTIFICATE-----, into a file on your local file system. For this example we'd save it as example.pem. Now we can give this certificate to the mongo command like so:

$ mongo -ssl -sslCAFile example.pem example.dblayer.com:10373/admin -u user -p pass

Connecting Your Application

We're happy to provide assistance with your MongoDB installation, however for in depth application and driver support, do check out the appropriate documentation and communities for your specific language and the driver that your application is using.

The addition of SSL to Compose MongoDB means that whatever language and driver you use, they will need to support SSL connections. The simplest way to connect is to configure the driver to ignore certificate errors or validity and use it purely to encrypt the communications between the driver and the MongoDB server. The slightly more complex way to connect is to use the public certificate from the Compose console for the MongoDB instance with your driver. This will allow the driver to confirm it is talking to the server and not another server. You will still need to set it to not validate the certificate as Compose currently uses self-signed certificates.

While we will, in general, refer you to the driver documentation and communities, we have taken some of our experiences with common languages and drivers and written tutorials for them. And we are in the process of updating them to cover at least the simplest SSL connection option:

If you're looking for languages that you do not see above, please see the MongoDB.org Driver List.

Go / Golang, MongoDB and Compose

As in the other examples, this document assumes an environmental variable called MONGOHQ_URL with your Compose Connection string. To set this variable, execute the following in the shell:

export MONGODB_URL="mongodb://user:pass@server.compose.io/db_name"

The mgo driver is the standard mongo driver for go, and can be installed by:

go get gopkg.in/mgo.v2

The mgo documentation, which is available at http://labix.org/mgo, covers most typical connections but as Compose MongoDB has SSL enabled, there are some extra steps to create and pass the TLS configuration to the mgo Dial function.

Connecting with Go without certificate validation

package main

import (
	"crypto/tls"
	"fmt"
	"net"
	"os"
	"strings"

	"gopkg.in/mgo.v2"
)

func main() {
	uri := os.Getenv("MONGODB_URL")
	if uri == "" {
		fmt.Println("No connection string provided - set MONGODB_URL")
		os.Exit(1)
	}
	uri = strings.TrimSuffix(uri, "?ssl=true")

	tlsConfig := &tls.Config{}
	tlsConfig.InsecureSkipVerify = true

	dialInfo, err := mgo.ParseURL(uri)

	if err != nil {
		fmt.Println("Failed to parse URI: ", err)
		os.Exit(1)
	}

	dialInfo.DialServer = func(addr *mgo.ServerAddr) (net.Conn, error) {
		conn, err := tls.Dial("tcp", addr.String(), tlsConfig)
		return conn, err
	}

	session, err := mgo.DialWithInfo(dialInfo)
	if err != nil {
		fmt.Println("Failed to connect: ", err)
		os.Exit(1)
	}

	defer session.Close()

	dbnames, err := session.DB("").CollectionNames()
	if err != nil {
		fmt.Println("Couldn't query for collections names: ", err)
		os.Exit(1)
	}

	fmt.Println(dbnames)

}

The line that removes "?ssl=true" from the URI (19) is needed as mgo will currently error if given the standard parameter for SSL/TLS connections.

Connecting with Go with certificate validation

To connect and verify the SSL Public Certificate of the server is essentially the same, but needs some additional steps to load the certificate, in this case from a file "servercert.crt":

package main

import (
	"crypto/tls"
	"crypto/x509"
	"io/ioutil"

	"fmt"
	"net"
	"os"
	"strings"

	"gopkg.in/mgo.v2"
)

func main() {
	uri := os.Getenv("MONGODB_URL")
	if uri == "" {
		fmt.Println("No connection string provided - set MONGODB_URL")
		os.Exit(1)
	}
	uri = strings.TrimSuffix(uri, "?ssl=true")

	roots := x509.NewCertPool()

	if ca, err := ioutil.ReadFile("servercert.crt"); err == nil {
		roots.AppendCertsFromPEM(ca)
	}

	tlsConfig := &tls.Config{}
	tlsConfig.RootCAs = roots

	dialInfo, err := mgo.ParseURL(uri)

	if err != nil {
		fmt.Println("Failed to parse URI: ", err)
		os.Exit(1)
	}

	dialInfo.DialServer = func(addr *mgo.ServerAddr) (net.Conn, error) {
		conn, err := tls.Dial("tcp", addr.String(), tlsConfig)
		return conn, err
	}

	session, err := mgo.DialWithInfo(dialInfo)
	if err != nil {
		fmt.Println("Failed to connect: ", err)
		os.Exit(1)
	}

	defer session.Close()

	dbnames, err := session.DB("").CollectionNames()
	if err != nil {
		fmt.Println("Couldn't query for collections names: ", err)
		os.Exit(1)
	}

	fmt.Println(dbnames)

}

Node.js / Native

Quick note: In this example, we are assuming that your Compose connection string is set in an environment variable MONGOHQ_URL, like this:

var MONGODB_URL="mongodb://user:pass@server.compose.io:port_name/db_name?ssl=true"

This code uses the node-mongodb-native driver, though in production you may want something a little less... nesty. Like all good Node packages, you can get it via NPM.

npm install mongodb

Connecting with Node.js (Javascript)

Here we connect, just enabling the SSL/TLS encryption without validating the server:

var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');

var options = {
    mongos: {
        ssl: true,
        sslValidate: false,
    }
}

MongoClient.connect(process.env.MONGODB_URL, options, function(err, db) {
    assert.equal(null, err);
    db.listCollections({}).toArray(function(err, collections) {
        assert.equal(null, err);
        collections.forEach(function(collection) {
            console.log(collection);
        });
        db.close();
        process.exit(0);
    })
});

If we want to use the server's SSL public certificate (stored in a file "servercert.crt" in this example) then we need to read it and include it in the options, while flipping sslValidate to true like this:

var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var fs = require('fs');

var ca = [fs.readFileSync(__dirname + "/servercert.crt")];

var options = {
    mongos: {
        ssl: true,
        sslValidate: true,
        sslCA:ca,
    }
}

MongoClient.connect(process.env.MONGODB_URL, options, function(err, db) {
    assert.equal(null, err);
    db.listCollections({}).toArray(function(err, collections) {
        assert.equal(null, err);
        collections.forEach(function(collection) {
            console.log(collection);
        });
        db.close();
        process.exit(0);
    })
});

If you prefer a more ES6 flavor to your examples try:

const MongoClient = require('mongodb').MongoClient;
import assert from 'assert';
import fs from 'fs';

const ca = [fs.readFileSync(`${__dirname}/servercert.crt`)];

const options = {
    mongos: {
        ssl: true,
        sslValidate: false,
        sslCA:ca,
    }
};

MongoClient.connect(process.env.MONGODB_URL, options, (err, db) => {
    assert.equal(null, err);
    db.listCollections({}).toArray((err, collections) => {
        assert.equal(null, err);
        collections.forEach((collection) => {
            console.log(collection);
        });
        db.close();
        process.exit(0);
    })
});

Connecting with Node.js (Coffeescript)

# npm install mongodb
mongodb = require 'mongodb'
url = require 'url'
log = console.log

connection_uri = url.parse(process.env.COMPOSE_URL)
db_name = connection_uri.pathname.replace(/^\//, '')

mongodb.Db.connect process.env.COMPOSE_URL, (error, client)->
  throw error if error

  client.collectionNames (error, names)->
    throw error if error

    # output all collection names
    log "Collections"
    log "==========="
    last_collection = null
    for col_data in names
      col_name = col_data.name.replace("#{db_name}.", '')
      log col_name
      last_collection = col_name

    collection = new mongodb.Collection(client, last_collection)
    log "\nDocuments in #{last_collection}"
    documents = collection.find({}, limit : 5)

    # output a count of all documents found
    documents.count (error, count)->
      log "  #{count} documents(s) found"
      log "===================="

      # output the first 5 documents
      documents.toArray (error, docs)->
        throw error if error

        for doc in docs then log doc

        # close the connection
        client.close()

That should do the trick!

Mongoose, Node and Compose

Quick note: In this example, we are assuming that your Compose connection string is set in an environment variable MONGODB_URL, like this:

var MONGODB_URL="mongodb://user:pass@server.compose.io:port_name/db_name"

This code uses the mongoose driver. Like all good Node packages, you can get it via NPM.

npm install mongoose

Connecting with Mongoose (Javascript)

The basic technique is the same as the Node.js/direct examples above. Create an options map, add in the requires SSL parameters and then pass that options map with the URL for MongoDB to the mongoose.connect() method. In the below example, we connect with a certificate and, again, list the available collections:

var mongoose = require('mongoose');
var assert = require('assert');
var fs = require('fs');

var ca = [ fs.readFileSync(__dirname + "/servercert.crt") ];

var options = {
    mongos: {
      ssl: true,
      sslValidate: true,
      sslCA: ca
    }
}

// If the connection throws an error
mongoose.connection.on('error',function (err) {
  console.log('Mongoose default connection error: ' + err);
});

mongoose.connection.on('open', function (err) {
    assert.equal(null, err);
    mongoose.connection.db.listCollections().toArray(function(err, collections) {
        assert.equal(null, err);
        collections.forEach(function(collection) {
            console.log(collection);
        });
        mongoose.connection.db.close();
        process.exit(0);
    })
});

// Let's open that connection
mongoose.connect(process.env.MONGODB_URL, options);

Ruby, MongoDB and Compose

Quick note: In this example, we are assuming that your Compose connection string is set in an environment variable MONGODB_URL, like this:

MONGODB_URL="mongodb://user:pass@server.compose.io/db_name"

If you are using Ruby (along with frameworks like Ruby on Rails, Sinatra, etc.), you can start out by installing the mongo (2.x) gem. It should go without saying, but you will need RubyGems. If you are using a pre-1.9 Ruby, you'll need to add require 'rubygems' at the start of the examples.

Without using a certificate, the code is simply:

require 'mongo'

Mongo::Logger.logger.level = ::Logger::FATAL

def client
  @client ||= Mongo::Client.new(ENV['MONGODB_URL'],
                    ssl:true,
                    ssl_verify: false)
end

db = client.database

collections = db.collection_names
puts collections # ["coll1", "coll2", ...]

The Logger line mutes the driver's debug messages (there's a lot of them). Comment it out if you want to see more.

To connect with a certificate, the code is similar, but more option settings are needed when connecting:

require 'mongo'

# Mongo::Logger.logger.level = ::Logger::FATAL

def client
    @client ||= Mongo::Client.new(ENV['MONGODB_URL'],
                ssl: true,
                ssl_verify: true,
                ssl_cert: './servercert.crt',
                ssl_cacert: './servercert.crt')
end

db = client.database

collections = db.collection_names
puts collections # ["coll1", "coll2", ...]

Note the servercert.crt file name being passed twice to denote the certificate is also its own authority.

Python, MongoDB and Compose

Quick note: In this example, we are assuming that your Compose connection string is set in an environment variable MONGODB_URL, like this:

MONGODB_URL="mongodb://user:pass@server.compose.io/database_name"

If you are using Python, you can start out by installing PyMongo.

import os
import pymongo
import ssl

MONGODB_URL = os.environ.get('MONGODB_URL')
client = pymongo.MongoClient(MONGODB_URL,ssl_cert_reqs=ssl.CERT_NONE)
db = client.get_default_database()
print db.collection_names()

To use the server's SSL certificate, it's simply a matter of adding it as a parameter like so:

import os
import pymongo
import ssl

MONGODB_URL = os.environ.get('MONGODB_URL')
client = pymongo.MongoClient(MONGODB_URL,ssl_ca_certs="./servercert.crt")
db = client.get_default_database()
print db.collection_names()

And then, you should be on your way.

PHP, MongoDB, and Compose

Quick note: In this example, we are assuming that your Compose connection string is set in an environment variable MONGODB_URL, like this:

export MONGODB_URL="mongodb://user:pass@server.compose.io/db_name"

This originally began as a Gist from Larry Hitchon of AppFog. We made some improvements and made it Compose-centric. It's a pretty straightforward driver. If you don't have PECL, you should install PECL.

    sudo pecl install mongo

And then, to the code sample:

<!-- PHP Mongo Docs: http://php.net/manual/en/class.mongodb.php -->
<!-- PHP Mongo Docs: http://php.net/manual/en/class.mongodb.php -->
<html>
<body>
<h1>Compose Test</h1>
<?php
  try {
    // connect to Compose assuming your MONGODB_URL environment
    // variable contains the connection string
    $connection_url = getenv("MONGODB_URL");

     // create the mongo connection object
    $m = new MongoClient($connection_url, array("ssl" => true));

    // extract the DB name from the connection path
    $url = parse_url($connection_url);
    $db_name = preg_replace('/\/(.*)/', '$1', $url['path']);

    // use the database we connected to
    $db = $m->selectDB($db_name);

    echo "<h2>Collections</h2>";
    echo "<ul>";

    // print out list of collections
    $cursor = $db->listCollections();
    $collection_name = "";
    foreach( $cursor as $doc ) {
      echo "<li>" .  $doc->getName() . "</li>";
      $collection_name = $doc->getName();
    }
    echo "</ul>";

    // print out last collection
    if ( $collection_name != "" ) {
      $collection = $db->selectCollection($collection_name);
      echo "<h2>Documents in ${collection_name}</h2>";

      // only print out the first 5 docs
      $cursor = $collection->find();
      $cursor->limit(5);
      echo $cursor->count() . ' document(s) found. <br/>';
      foreach( $cursor as $doc ) {
        echo "<pre>";
        var_dump($doc);
        echo "</pre>";
      }
    }

    // disconnect from server
    $m->close();
  } catch ( MongoConnectionException $e ) {
    die('Error connecting to MongoDB server');
  } catch ( MongoException $e ) {
    die('Mongo Error: ' . $e->getMessage());
  } catch ( Exception $e ) {
    die('Error: ' . $e->getMessage());
  }
?>
</body>
</html>

That should get you well on your way.

C# / .NET, MongoDB and Compose

This guide assumes that you have already downloaded and installed the MongoDB C# driver for your project.

If you have not done so, you can find the installer at: http://github.com/mongodb/mongo-csharp-driver/downloads.

Once installation is complete, you will be able to reference the MongoDriver and MongoBSON DLLs within Visual Studio.

Create a New Project

To begin, letʼs create a new project in Visual Studio. I chose to use ASP.NET MVC 2 Web Application in this example. (The examples given can be easily ported to WebForms if necessary.)

Creating a project in Visual Studio.

Creating a project in Visual Studio.

Add References

Now we will need to reference the MongoDriver and MongoBSON DLLs so that we can connect to our MongoDB database. The C# driver installer added these two DLLs to the .NET tab of your reference window.

With these references added, we are now able to connect and query our Compose database with just a few lines of code.

Adding a reference from the .NET list.

Adding a reference from the .NET list.

Add Connection Information

Next, let's set up our connection string with our database information by adding a new connection string in our application's web.config file. The entry should look similar to this:

<connectionStrings>
  <add name="ApplicationServices"
    connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
    providerName="System.Data.SqlClient" />
  <add name="Compose"
    connectionString="your mongo uri"/>
</connectionStrings>

Of course, your mongo uri should be replaced with the actual Compose URI that is provided to you in the web interface. You can get this by doing the following:

  1. Log into Compose
  2. Click on the port number of the database you want to connect to
  3. Copy or note the URI that is provided.

You will just need the root URI, so you can choose any database you would like.

Setting up your Model and Controller

Now, let's create a model to hold our documents. The database used in this example is a collection of developers with basic information, so we will create a Data Transformation Object (DTO) to store these properties and return a generic list of these DTOs in our model.

Create a DTO directory under the Model directory for our DeveloperDTO.cs file.

namespace mongodb_csharp.Models.DTO
{
  public class DeveloperDTO
  {
    public BsonObjectId id { get; set; }
    public string name { get; set; }
    public string languages { get; set; }
    public string company { get; set; }
  }
}

Add our DeveloperModel.cs to the Models directory. Make sure you include a using clause for the DTO directory.

using System.Collections.Generic;
using mongodb_csharp.Models.DTO;
 
namespace mongodb_csharp.Models
{
  public class DeveloperModel
  {
    public IList<DeveloperDTO> developers { get; set; }
  }
}

Now let's create our DeveloperController.

In this example, let's name it DeveloperController. You can uncheck the box for "Add action methods for Create, Update and Delete Scenarios" as we won't be covering this functionality in the Getting Started guide.

Open your newly created controller and add your using clauses. At a minimum, you should have the following.

Notice the highlighted line where we are declare a private MongoDatabase object and instantiating it in our constructor.

using System.Linq;
using System.Web.Mvc;
using System.Configuration;
using MongoDB.Driver;
using mongodb_csharp.Models;
using cimpose_csharp.Models.DTO;

namespace mongodb_csharp.Controllers
{
    public class DeveloperController : Controller
    {
        readonly MongoDatabase mongo_db;

        public DeveloperController()
        {
            mongo_db = retreive_mongodb_db();
        }

        public ActionResult Index()
        {
            var model = new DeveloperModel();
            var developers_collection = mongo_db.GetCollection("developers").FindAll().AsEnumerable();

            model.developers = (from developer in developers_collection
                                select new DeveloperDTO
                                           {
                                               id = developer["_id"].AsObjectId,
                                               name = developer["name"].AsString,
                                               languages = developer["languages"].AsBsonArray.ToString(),
                                               company = developer["company"].AsString
                                           }).ToList();

            return View(model);
        }
        
        static MongoDatabase retreive_mongodb_db()
        {
            return MongoServer.Create(
                ConfigurationManager.ConnectionStrings["Compose"].ConnectionString)
                .GetDatabase("t2");
        }
    }
}

As you can see, I broke the database call into a separate method, which is listed below. Here, we utilize the MongoServer.Create method to initialize a connection to our Compose server using our connection string from our web.config. Now we can call GetDatabase to get our MongoDatabase instance.

In this case, my database name is t2.

For more information on these methods, take a look at the CSharp Driver Tutorial.

static MongoDatabase retreive_mongodb_db()
{
  return MongoServer.Create(
    ConfigurationManager.ConnectionStrings["Compose"].ConnectionString)
    .GetDatabase("t2");
}

Add an Index method to our DeveloperController

Now that our connections are set up, let's add a method to our DeveloperController.cs that will assist in delivering the database content to our soon-to-be created view.

public ActionResult Index()
{
  var model = new DeveloperModel();
  var developers_collection = mongo_db.GetCollection("developers").FindAll().AsEnumerable();
 
  model.developers = (from developer in developers_collection
                        select new DeveloperDTO
                        {
                          id = developer["_id"].AsObjectId,
                          name = developer["name"].AsString,
                          languages = developer["languages"].AsBsonArray.ToString(),
                          company = developer["company"].AsString
                        }).ToList();
 
  return View(model);
}

Success!

We now have a connection to our database and a method to deliver the content to our view. All we need to do now is hydrate our model and pass it to the view.

Viewing Data

In this example, we simply iterate over our developers and print them to the screen. Create a Developer folder in the Views directory and add a new .aspx file called Index.aspx. Add the code below and youʼre all set.

<%%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<mongodb_csharp.Models.DeveloperModel>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
  Index
</asp:Content>
 
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
 
  <h2>Developers</h2>

  <ul>
    <%% foreach(var developer in Model.developers) { %>
      <li><%%= developer.name %> works for <%%= developer.company %> and is proficient in <%%= developer.languages %></li>
    <%% } %>
  </ul>
</asp:Content>

For more information, please check out the MongoDB C# Driver API documentation.


Still Need Help?

If this article didn't solve things, summon a human and get some help!

Connecting to MongoDB