Develop locally using the Azure Cosmos DB emulator

A common use case for the emulator is to serve as a development database while you're building your applications. Using the emulator for development can help you learn characteristics of creating and modeling data for a database like Azure Cosmos DB without incurring any service costs. Additionally, using the emulator as part of an automation workflow can ensure that you can run the same suite of integration tests. You can ensure that the same tests run both locally on your development machine and remotely in a continuous integration job.

Prerequisites

Install the emulator

There are multiple variations of the emulator and each variation has a relatively frictionless install process.

To get started, get the Linux-variant of the container image from the Microsoft Container Registry (MCR).

  1. Pull the mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator Linux container image from the container registry to the local Docker host.

    docker pull mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest
    
  2. Check to make sure that the emulator image is available on your local Docker host.

    docker images
    

To get started, get the Linux-variant of the container image from the Microsoft Container Registry (MCR).

  1. Pull the mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator Linux container image using the mongodb tag from the container registry to the local Docker host.

    docker pull mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:mongodb
    
  2. Check to make sure that the emulator image is available on your local Docker host.

    docker images
    

The Docker container variant (Linux or Windows) of the emulator doesn't support the API for Apache Cassandra, API for Apache Gremlin, or API for Table.

Start the emulator

Once downloaded, start the emulator with your specified API enabled.

The Docker container variant of the emulator doesn't support the API for Apache Cassandra.

The Docker container variant of the emulator doesn't support the API for Apache Gremlin.

The Docker container variant of the emulator doesn't support the API for Table.

  1. Run a new container using the container image and the following configuration:

    Description
    AZURE_COSMOS_EMULATOR_PARTITION_COUNT (Optional) Specify the number of partitions to use.
    AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE (Optional) Enable data persistence between emulator runs.
    AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE (Optional) Override the emulator's default IP address.

    For Linux systems, use:

    docker run \
        --publish 8081:8081 \
        --publish 10250-10255:10250-10255 \
        --name linux-emulator \
        --detach \
        mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest    
    

    For Windows systems, use:

    $parameters = @(
        "--publish", "8081:8081"
        "--publish", "10250-10255:10250-10255"
        "--name", "windows-emulator"
        "--detach"
    )
    docker run @parameters mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest 
    
  2. Navigate to https://localhost:8081/_explorer/index.html to access the data explorer.

  1. Run a new container using the container image and the following configuration:

    Description
    AZURE_COSMOS_EMULATOR_ENABLE_MONGODB_ENDPOINT Specify the version of the MongoDB endpoint to use. Supported endpoints include: 3.2, 3.6, or 4.0.
    AZURE_COSMOS_EMULATOR_PARTITION_COUNT (Optional) Specify the number of partitions to use.
    AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE (Optional) Enable data persistence between emulator runs.
    AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE (Optional) Override the emulator's default IP address.

    For Linux systems, use:

    docker run \
        --publish 8081:8081 \
        --publish 10250:10250 \
        --env AZURE_COSMOS_EMULATOR_ENABLE_MONGODB_ENDPOINT=4.0 \
        --name linux-emulator \
        --detach \
        mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:mongodb
    

    For Windows systems, use:

    $parameters = @(
        "--publish", "8081:8081"
        "--publish", "10250:10250"
        "--env", "AZURE_COSMOS_EMULATOR_ENABLE_MONGODB_ENDPOINT=4.0"
        "--name", "windows-emulator"
        "--detach"
    )
    docker run @parameters mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:mongodb
    
  2. Navigate to https://localhost:8081/_explorer/index.html to access the data explorer.

Import the emulator's TLS/SSL certificate

Import the emulator's TLS/SSL certificate to use the emulator with your preferred developer SDK without disabling TLS/SSL on the client.

The Docker container variant (Linux or Windows) of the emulator doesn't support the API for Apache Cassandra, API for Apache Gremlin, or API for Table.

The certificate for the emulator is available at the path _explorer/emulator.pem on the running container. Use curl to download the certificate from the running container to your local machine.

  1. Get the certificate from the running container.

    For Linux systems, use:

    curl --insecure https://localhost:8081/_explorer/emulator.pem > ~/emulatorcert.crt
    

    For Windows systems, use:

    $parameters = @{
        Uri = 'https://localhost:8081/_explorer/emulator.pem'
        Method = 'GET'
        OutFile = 'emulatorcert.crt'
        SkipCertificateCheck = $True
    }
    Invoke-WebRequest @parameters
    
  2. Regenerate the certificate bundle by using the appropriate command for your operating system.

    For Debian-based Linux systems (for example, Ubuntu), use:

    sudo update-ca-certificates
    

    For Red Hat-based Linux systems (for example, CentOS, Fedora), use:

    sudo update-ca-trust
    

    For Windows systems, use:

    certutil -f -addstore "Root" ~/emulatorcert.crt
    

    For more detailed instructions, consult the documentation specific to your operating system.

The certificate for the emulator is available at the path /_explorer/emulator.pem on the running container.

  1. Download the certificate from the running container to your local machine.

    For Linux systems, use:

    curl --insecure https://localhost:8081/_explorer/emulator.pem > ~/emulatorcert.crt
    

    For Windows systems, use:

    $parameters = @{
        Uri = 'https://localhost:8081/_explorer/emulator.pem'
        Method = 'GET'
        OutFile = 'emulatorcert.crt'
        SkipCertificateCheck = $True
    }
    Invoke-WebRequest @parameters
    

    Note

    You may need to change the host (or IP address) and port number if you have previously modified those values.

  2. Install the certificate according to the process typically used for your operating system. For example, in Linux you would copy the certificate to the /usr/local/share/ca-certificates/ path.

    For Linux systems, use:

    cp ~/emulatorcert.crt /usr/local/share/ca-certificates/
    

    For Windows systems, use:

    $parameters = @{
        FilePath = 'emulatorcert.crt'
        CertStoreLocation = 'Cert:\CurrentUser\Root'
    }
    Import-Certificate @parameters
    
  3. For linux systems, regenerate the certificate bundle by using the appropriate command for your Linux distribution.

    For Debian-based Linux systems (for example, Ubuntu), use:

    sudo update-ca-certificates
    

    For Red Hat-based Linux systems (for example, CentOS, Fedora), use:

    sudo update-ca-trust
    

    For more detailed instructions, consult the documentation specific to your operating system.

Connect to the emulator from the SDK

Each SDK includes a client class typically used to connect the SDK to your Azure Cosmos DB account. By using the emulator's credentials, you can connect the SDK to the emulator instance instead.

Use the Azure Cosmos DB API for NoSQL .NET SDK to connect to the emulator from a .NET application.

  1. Start in an empty folder.

  2. Create a new .NET console application

    dotnet new console
    
  3. Add the Microsoft.Azure.Cosmos package from NuGet.

    dotnet add package Microsoft.Azure.Cosmos
    
  4. Open the Program.cs file.

  5. Delete any existing content within the file.

  6. Add a using block for the Microsoft.Azure.Cosmos namespace.

    using Microsoft.Azure.Cosmos;
    
  7. Create a new instance of CosmosClient using the emulator's credentials.

    using CosmosClient client = new(
        accountEndpoint: "https://localhost:8081/",
        authKeyOrResourceToken: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
    );
    
  8. Create a new database and container using CreateDatabaseIfNotExistsAsync and CreateContainerIfNotExistsAsync.

    Database database = await client.CreateDatabaseIfNotExistsAsync(
        id: "cosmicworks",
        throughput: 400
    );
    
    Container container = await database.CreateContainerIfNotExistsAsync(
        id: "products",
        partitionKeyPath: "/id"
    );
    
  9. Create a new item in the container using UpsertItemAsync.

    var item = new
    {
        id = "68719518371",
        name = "Kiama classic surfboard"
    };
    
    await container.UpsertItemAsync(item);
    
  10. Run the .NET application.

    dotnet run
    

    Warning

    If you get a SSL error, you may need to disable TLS/SSL for your application. This commonly occurs if you are developing on your local machine, using the Azure Cosmos DB emulator in a container, and have not imported the container's SSL certificate. To resolve this, configure the client's options to disable TLS/SSL validation before creating the client:

    CosmosClientOptions options = new ()
    {
        HttpClientFactory = () => new HttpClient(new HttpClientHandler()
        {
            ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
        }),
        ConnectionMode = ConnectionMode.Gateway,
    };
    
    using CosmosClient client = new(
      ...,
      ...,
      clientOptions: options
    );
    

Tip

Refer to the .NET developer guide for more operations you can perform using the .NET SDK.

Use the MongoDB .NET driver to connect to the emulator from a .NET application.

  1. Start in an empty folder.

  2. Create a new .NET console application

    dotnet new console
    
  3. Add the MongoDB.Driver package from NuGet.

    dotnet add package MongoDB.Driver
    
  4. Open the Program.cs file.

  5. Delete any existing content within the file.

  6. Add a using block for the MongoDB.Driver namespace.

    using MongoDB.Driver;
    
  7. Create a new instance of MongoClient using the emulator's credentials.

    var client = new MongoClient(
        "mongodb://localhost:C2y6yDjf5%2FR%2Bob0N8A7Cgv30VRDJIWEHLM%2B4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw%2FJw%3D%3D@localhost:10255/admin?ssl=true&retrywrites=false"
    );
    
  8. Get the database and container using GetDatabase and GetCollection<>.

    var database = client.GetDatabase("cosmicworks");
    
    var collection = database.GetCollection<dynamic>("products");
    
  9. Create a new item in the XXX using InsertOneAsync.

    var item = new
    {
        name = "Kiama classic surfboard"
    };
    
    await collection.InsertOneAsync(item);
    
  10. Run the .NET application.

    dotnet run
    

Use the Apache Cassandra .NET driver to connect to the emulator from a .NET application.

  1. Start in an empty folder.

  2. Create a new .NET console application

    dotnet new console
    
  3. Add the CassandraCSharpDriver package from NuGet.

    dotnet add package CassandraCSharpDriver
    
  4. Open the Program.cs file.

  5. Delete any existing content within the file.

  6. Add a using block for the Cassandra namespace.

    using Cassandra;
    
  7. Create a new instance of Cluster using the emulator's credentials. Create a new session using Connect.

    var options = new SSLOptions(
        sslProtocol: System.Security.Authentication.SslProtocols.Tls12,
        checkCertificateRevocation: true,
        remoteCertValidationCallback: (_, _, _, policyErrors) => policyErrors == System.Net.Security.SslPolicyErrors.None);
    
    using var cluster = Cluster.Builder()
        .WithCredentials(
            username: "localhost",
            password: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
        )
        .WithPort(
            port: 10350
        )
        .AddContactPoint(
            address: "localhost"
        )
        .WithSSL(
            sslOptions: options
        )
        .Build();
    
    using var session = cluster.Connect();
    
  8. Create a new database and container using PrepareAsync and ExecuteAsync.

    var createKeyspace = await session.PrepareAsync("CREATE KEYSPACE IF NOT EXISTS cosmicworks WITH replication = {'class':'basicclass', 'replication_factor': 1};");
    await session.ExecuteAsync(createKeyspace.Bind());
    
    var createTable = await session.PrepareAsync("CREATE TABLE IF NOT EXISTS cosmicworks.products (id text PRIMARY KEY, name text)");
    await session.ExecuteAsync(createTable.Bind());
    
  9. Create a new item in the table using ExecuteAsync. Use Bind to assign properties to the item.

    var item = new
    {
        id = "68719518371",
        name = "Kiama classic surfboard"
    };
    
    var createItem = await session.PrepareAsync("INSERT INTO cosmicworks.products (id, name) VALUES (?, ?)");
    
    var createItemStatement = createItem.Bind(item.id, item.name);
    
    await session.ExecuteAsync(createItemStatement);
    
  10. Run the .NET application.

    dotnet run
    

Important

Prior to starting, the API for Apache Gremlin requires you to create your resources in the emulator. Create a database named db1 and a container named coll1. The throughput settings are irrelevant for this guide and can be set as low as you'd like.

Use the Apache Gremlin .NET driver to connect to the emulator from a .NET application.

  1. Start in an empty folder.

  2. Create a new .NET console application

    dotnet new console
    
  3. Add the Gremlin.Net package from NuGet.

    dotnet add package Gremlin.Net 
    
  4. Open the Program.cs file.

  5. Delete any existing content within the file.

  6. Add a using block for the Gremlin.Net.Driver namespace.

    using Gremlin.Net.Driver;
    
  7. Create a new instance of GremlinServer and GremlinClient using the emulator's credentials.

    var server = new GremlinServer(
        hostname: "localhost",
        port: 8901,
        username: "/dbs/db1/colls/coll1",
        password: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
    );
    
    using var client = new GremlinClient(
        gremlinServer: server,
        messageSerializer: new Gremlin.Net.Structure.IO.GraphSON.GraphSON2MessageSerializer()
    );
    
  8. Clean up the graph using SubmitAsync.

    await client.SubmitAsync(
        requestScript: "g.V().drop()"
    );
    
  9. Use SubmitAsync again to add a new item to the graph with the specified parameters.

    await client.SubmitAsync(
        requestScript: "g.addV('product').property('id', prop_id).property('name', prop_name)",
        bindings: new Dictionary<string, object>
        {
            { "prop_id", "68719518371" },
            { "prop_name", "Kiama classic surfboard" }
        }
    );
    
  10. Run the .NET application.

    dotnet run
    

Use the Azure Tables SDK for .NET to connect to the emulator from a .NET application.

  1. Start in an empty folder.

  2. Create a new .NET console application

    dotnet new console
    
  3. Add the Azure.Data.Tables package from NuGet.

    dotnet add package Azure.Data.Tables
    
  4. Open the Program.cs file.

  5. Delete any existing content within the file.

  6. Add a using block for the Azure.Data.Tables namespace.

    using Azure.Data.Tables;
    
  7. Create a new instance of TableServiceClient using the emulator's credentials.

    var serviceClient = new TableServiceClient(
        connectionString: "DefaultEndpointsProtocol=http;AccountName=localhost;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==;TableEndpoint=http://localhost:8902/;"
    );
    
  8. Use GetTableClient to create a new instance of TableClient with the table's name. Then ensure the table exists using CreateIfNotExistsAsync.

    var client = serviceClient.GetTableClient(
        tableName: "cosmicworksproducts"
    );
    
    await client.CreateIfNotExistsAsync();
    
  9. Create a new record type for items.

    public record Product : Azure.Data.Tables.ITableEntity
    {
        public required string RowKey { get; set; }
    
        public required string PartitionKey { get; set; }
    
        public required string Name { get; init; }
    
        public Azure.ETag ETag { get; set; }
    
        public DateTimeOffset? Timestamp { get; set; }
    }
    
  10. Create a new item in the table using UpsertEntityAsync and the Replace mode.

    var item = new Product
    {
        RowKey = "68719518371",
        PartitionKey = "Surfboards",
        Name = "Kiama classic surfboard",
        Timestamp = DateTimeOffset.Now
    };
    
    await client.UpsertEntityAsync(
        entity: item,
        mode: TableUpdateMode.Replace
    );
    
  11. Run the .NET application.

    dotnet run
    

Use the emulator in a GitHub Actions CI workflow

To run a continuous integration workload that automatically validates your application, use the Azure Cosmos DB emulator with a test suite from your framework of choice. The Azure Cosmos DB emulator is preinstalled in the windows-latest variant of GitHub Action's hosted runners.

Run a test suite using the built-in test driver for .NET and a testing framework such as MSTest, NUnit, or XUnit.

  1. Validate that the unit test suite for your application works as expected.

    dotnet test
    
  2. Create a new workflow in your GitHub repository in a file named .github/workflows/ci.yml.

  3. Add a job to your workflow to start the Azure Cosmos DB emulator using PowerShell and run your unit test suite.

    name: Continuous Integration
    on:
      push:
        branches:
          - main
    jobs:
      unit_tests:
        name: Run .NET unit tests
        runs-on: windows-latest
        steps:
          - name: Checkout (GitHub)
            uses: actions/checkout@v3
          - name: Start Azure Cosmos DB emulator
            run: |
              Write-Host "Launching Cosmos DB Emulator"
              Import-Module "$env:ProgramFiles\Azure Cosmos DB Emulator\PSModules\Microsoft.Azure.CosmosDB.Emulator"
              Start-CosmosDbEmulator
          - name: Run .NET tests
            run: dotnet test
    

    Note

    Start the emulator from the command line using various arguments or PowerShell commands. For more information, see emulator command-line arguments.

Next step