Develop with CosmosDB in Docker
Micro services are increasingly more popular in new development project. In this post I'll show you how to connect to a CosmosDB emulator from your docker app.
CosmosDB emulator on host
The CosmosDB emulator is locked down to localhost by default. To allow calls from within the docker cluster you need to open up for network access. This is done by adding the
AllowNetworkAccess parameter at startup. You also need to specify a new access key. The key needs to be a Base64 encoded 64 character long string, like this one.
A custom startup script for the CosmosDB emulator could look like this:
1 "c:\Program Files\Azure Cosmos DB Emulator\CosmosDB.Emulator.exe" /AllowNetworkAccess /Key=YWJjZGVmZ2hpamtsbW5vcHFyc3RhYmNkZWZnaGlqa2xtbm9wcXJzdGFiY2RlZmdoaWprbG1ub3BxcnN0YWJjZA==
To connect to the CosmosDB emulator from your docker app you can’t use
localhost:8081 anymore since that refers to your docker instance and not the host machine. Instead, if you’re using a newer version of docker, then you can use
https://host.docker.internal:8081 to connect to CosmosDB.
If you have an older version of docker then you’ll need to connect by IP which works just as fine.
CosmosDB emulator as docker container
Another way to run the CosmosDB emulator locally is to run it as a container and Microsoft is providing a prepared solution for this. There are different ways to configure your container and you can find more information about it on the docker image page.
For a basic scenario you can run the following commands to setup a container.
1 2 3 4 5 cmd set containerName=azure-cosmosdb-emulator set hostDirectory=%LOCALAPPDATA%\azure-cosmosdb-emulator.hostd md %hostDirectory% 2>nul docker run --name %containerName% --memory 2GB --mount "type=bind,source=%hostDirectory%,destination=C:\CosmosDB.Emulator\bind-mount" --interactive --tty -p 8081:8081 -p 8900:8900 -p 8901:8901 -p 8979:8979 -p 10250:10250 -p 10251:10251 -p 10252:10252 -p 10253:10253 -p 10254:10254 -p 10255:10255 -p 10256:10256 -p 10350:10350 microsoft/azure-cosmosdb-emulator
This will download an image of around 10Gb in size so make sure you have a good internet connection. A few things to note for this setup:
It will bind the ports used by CosmosDB from the container to your host machine. This means that you shouldn’t try to run the emulator on the host itself.
CosmosDB emulator will generate a certificate to a local folder. The command binds that local folder to
%LOCALAPPDATA%\azure-cosmosdb-emulator.hostd. From your host machine you’ll be able to access this new certificate together with a powershell script to help you import this certificate.
A container named
azure-cosmosdb-emulatorwill be created. If you try to run the last command a second time you’ll get an error. Instead, use the commands
docker start azure-cosmosdb-emulatorand
docker stop azure-cosmosdb-emulatorto handle your container.
Browsing to the emulator explorer
Since we linked port 8081 when starting the emulator container earlier on, we can now browse the emulator explorer just like we would when running the emulator on the host machine using the address
Using the right Windows container version
When I started to build this solution my Windows host only supported Windows containers of version 1803. This turned out to be a problem due to a bug which in some situations set the UTC time to be UTC-8 hours (Redmond time, hmmm?). In my case it caused the CosmosDB emulator (or maybe the client) to fail all calls since it only allows a time skew of 15 minutes. There was apparently quite some written on Internet about this (always nice to know you’re not the first one encountering this problem) and the solution was either to change how
docker run executes the container or to upgrade Windows to higher version. The former solution would prevent me from using Visual Studio Docker tools and wasn’t a preferred option. I therefore opted for a Windows upgrade.
The current windows container being used in these examples is
mcr.microsoft.com/dotnet/core/aspnet:2.2-nanoserver-1903 and the time bug has been fixed here.
Installing the docker image for CosmosDB Emulator includes a lot of fuss. It works just fine to connect to a standard Windows installation from the docker app so my recommendation is therefore to keep it simple.