NOTE: 22/07/2023
Microsoft claims in its Github repository that the emulator does not work on Linux:
Github repository as of: 22/July/2023.
There is also a comment via this Landing Page that CosmosDB for Linux Docker is in Preview:
https://learn.microsoft.com/en-us/azure/cosmos-db/local-emulator?tabs=ssl-netstd21
...and specifically:
TL;DR: use at your own risk. Pay attention to the links in the references around the Linux CosmosDB emulator no longer working in Azure DevOps Pipelines if using this for integration testing and MacOS support (Intel Chips only at this time - see above link).
The problem
The Azure Cosmos Emulator for Linux (Preview) creates a new certificate every time it is started; and by default the certificate is only configured to use IP addresses for its alternative names (no DNS). Therefore, when working in the likes of ephemeral .devcontainers, we cannot directly access https://cosmosdb:8081 from another container even if that container trusts the certificate. Some languages - such as Node via the NODE_TLS_REJECT_UNAUTHORIZED environment variable - can disable TLS verification; and other languages - such as .Net - can do it via modifying the verification by providing a callback handler - which needs access to the code. However: it is better to resolve these issues at the infrastructure level.
The solution
The solution is quite straight forward: there are four things we need to do:
CosmosDB Emulator Container
There is one problem the CosmosDB Container must solve so that clients in the same docker-compose can access it via its service name:
- We need to provide the name of the CosmosDB service in docker-compose via the AZURE_COSMOS_EMULATOR_ARGS environment variable when we start docker-compose. Thats all!
CosmosDb Clients in other containers
There are three problems CosmosDB Clients in the same docker-compose must solve if they want to access CosmosDB by its docker-compose service name:
- They must wait for CosmosDB to be ready. This is indicated by the availability of the certificate from the CosmosDB URL. We need to use a tool such as
curl --insecure
to poll the availability of the certificate because we cannot trust the certificate until it exists. Therefore, this must happen as early as possible during container initialization. - They must trust the CosmosDB SSL certificate.
- They must access the CosmosDB instance via its DNS/docker-compose service name
Example
An example is included - just:
docker compose up
The scripts
folder is mounted in the CosmosDB Client and contains the waiting and certificate trusting logic.
Musing: View generated certificate
To view the CosmosDB certificate, its settings, alternative names and so forth, execute this from the HOST machine, after the docker-compose is:
curl --insecure https://localhost:18081/_explorer/emulator.pem > emulator.crt
openssl x509 -in emulator.crt -text -noout
Musing: Access from host
To access CosmosDB from the host once it has started:
https://localhost:18081/_explorer/index.html
Musing: View entrypoint script
The CosmosDb entrypoint is currently start.sh
and can be viewed like this:
# Find THEID
docker container ls
docker exec THEID cat /usr/local/bin/cosmos/start.sh
This repository is based on the PREVIEW version - so this solution is likely brittle. Ideally, it would be possible to add extra /alternativenames using a specific environment variable but there is no way currently.
References
Link | Reference |
---|---|
https://learn.microsoft.com/en-us/azure/cosmos-db/local-emulator?tabs=ssl-netstd21 | Landing page for running the emulator on all OS's (and Docker on those OS's) |
https://github.com/Azure/azure-cosmos-db-emulator-docker | Github repo for the emulator |
https://docs.microsoft.com/en-us/azure/cosmos-db/linux-emulator?tabs=ssl-netstd21 | In particular: ..."can also be used for signaling when the emulator endpoint is ready" |
https://mcr.microsoft.com/v2/cosmosdb/linux/azure-cosmos-emulator/tags/list | View the tags for the Linux Cosmos Emulator |
Azure/azure-cosmos-db-emulator-docker#56 | Linux emulator failing on GHA Ubuntu 20.04 and 22.04 (TL;DR: doesn't work on Azure DevOps as of June 2023) |