DEV Community

Cover image for How to Expose Azure Cosmos DB Emulator to the Internet using ngrok & Docker
Er. Ankit Parashar
Er. Ankit Parashar

Posted on

How to Expose Azure Cosmos DB Emulator to the Internet using ngrok & Docker

Testing cloud-native apps locally is great, but things get tricky when you need to access your local database from a mobile device, a webhook, or a remote colleague's machine.

In this guide, we’ll containerize the Azure Cosmos DB Emulator and use ngrok to create a secure tunnel to the public internet.

The Architecture

  1. Docker: Runs the Cosmos DB Linux Emulator.
  2. ngrok: Creates a secure HTTPS tunnel to your local port.
  3. Node.js App: Connects to the ngrok URL using specific configurations to bypass local certificate and discovery hurdles.

1. Start the Cosmos DB Emulator

Run the following command in your terminal.

Important: Replace 192.168.1.17 with your machine's actual Local IP address (find this via ipconfig on Windows or ifconfig on Mac/Linux).

docker run

--publish 8081:8081
--publish 1234:1234

--name cosmos-emulator
--env AZURE_COSMOS_EMULATOR_GATEWAY_ADVERTISE_HOST=192.168.1.17

--env AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE=192.168.1.17

mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:vnext-preview

  1. Fire up the ngrok Tunnel Once the container is healthy, expose port 8081. We must use the --host-header rewrite flag because the Cosmos Emulator is picky about the hostnames it accepts.


ngrok http 8081 --host-header=rewrite

Copy the generated https://...ngrok-free.app URL. You'll need it for your connection string.

  1. The Node.js Client Setup Connecting to a tunneled emulator requires two specific "hacks" in your client configuration:

Disable Endpoint Discovery: This prevents the SDK from trying to find the "real" local IP and sticking to the ngrok URL instead.

Ignore Self-Signed Certs: Since the emulator uses a local dev cert, we need to tell the HTTPS agent to allow it.

The Code (index.js)

const { CosmosClient } = require("@azure/cosmos");
const https = require("https");

const client = new CosmosClient({
  endpoint: "https://YOUR_NEW_NGROK_URL.ngrok-free.app", 
  key: "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==",
  connectionPolicy: {
    enableEndpointDiscovery: false // Keeps the traffic flowing through ngrok
  },
  agent: new https.Agent({
    rejectUnauthorized: false // Bypasses self-signed certificate errors
  })
});

async function testConnection() {
  try {
    await client.databases.readAll().fetchAll();
    console.log("Success! You are connected via ngrok.");
  } catch (err) {
    console.error("Error:", err.message);
  }
}

testConnection();
Enter fullscreen mode Exit fullscreen mode

Key Takeaways
Port 8081: This is the Gateway port. Ensure it's open and mapped correctly.

Discovery Off: If enableEndpointDiscovery is true, your app will try to connect to 127.0.0.1 after the first request, breaking the remote tunnel connection.

Security: Never use rejectUnauthorized: false in a production environment. This is strictly for local emulator testing!

Troubleshooting
If you get a connection timeout:

Ensure your Docker container has finished starting up (it can take 60+ seconds).

Verify that your local firewall isn't blocking port 8081.

Check that the AZURE_COSMOS_EMULATOR_GATEWAY_ADVERTISE_HOST matches your current local IP.

Top comments (0)