Azure / azure-cosmos-db-emulator-docker

This repo serves as hub for managing issues, gathering feedback, and having discussions regarding the Cosmos DB Emulator Docker.
https://learn.microsoft.com/en-us/azure/cosmos-db/how-to-develop-emulator?tabs=docker-linux%2Ccsharp&pivots=api-nosql
MIT License
164 stars 47 forks source link

It's not possible to use development setup with Visual Studio using Docker Compose and Cosmos Db #47

Closed MatheusXavier closed 2 years ago

MatheusXavier commented 2 years ago

This is my current local development scenario:

I'm using this Docker image for Cosmos Db Emulator on Linux mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator, this is my issue: If I don't set the environment variable AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE then it's possible to access the cosmos db from the application, but it's not possible to access from my Integration Tests, otherwise if I set the variable AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE with the value 127.0.0.1 then it's possible to access from my integration tests but it is NOT possible to access from my application, this is the docker-compose.yml file:

version: '3.7'

services:

  cosmosdb:
    container_name: cosmos-db
    image: mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest
    cpus: 2.0
    mem_limit: 3g

  sqldata:
    container_name: sqlserver-db
    image: mcr.microsoft.com/mssql/server:2019-latest

  redisdata:
    container_name: redis-data
    image: redis:alpine

  rabbitmq:
    container_name: rabbit-mq
    image: rabbitmq:3-management-alpine

  service-api:
    container_name: service-api
    image: ${REGISTRY:-abc}/service.api:${PLATFORM:-linux}-${TAG:-latest}
    build:
      context: .
      dockerfile: src/Service.Backend.Web.API/Dockerfile
      network: host
    depends_on:
      - sqldata
      - redisdata
      - rabbitmq
      - cosmosdb

And here it's my docker-compose.override.yml file:

version: '3.7'

services:

  cosmosdb:
    environment:
       - AZURE_COSMOS_EMULATOR_PARTITION_COUNT=10
       - AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE=true
       - AZURE_COSMOS_EMULATOR_GREMLIN_ENDPOINT=true
       # If unncoment this line then it's possible to access from outside,
       # but the application can't reach the database
       #- AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE=127.0.0.1
    ports:
      - "8081:8081"
      - "8901:8901"
      - "8902:8902"
      - "10251:10251"
      - "10252:10252"
      - "10253:10253"
      - "10254:10254"
      - "10255:10255"
      - "10350:10350"
    volumes:
       - service-cosmosdbdata:/data/db

  sqldata:
    environment:
      - SA_PASSWORD=Pass@word
      - ACCEPT_EULA=Y
    ports:
      - "5434:1433"
    volumes:
      - service-sqldata:/var/opt/mssql

  redisdata:
    ports:
      - "6380:6379"
    volumes:
      - service-redisdata:/var/opt/redis

  rabbitmq:
    ports:
      - "15672:15672"
      - "5672:5672"
    volumes:
      - service-rabbit:/var/opt/rabbitmq

  service-api:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+:80
      - ASPNETCORE_Kestrel__Certificates__Default__Password=Pass@word
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
      - ConnectionStrings__DefaultConnection=Server=sqldata;Database=service-db;User Id=sa;Password=Pass@word
      - ConnectionStrings__EventStoreConnection=Server=sqldata;Database=eventstore-db;User Id=sa;Password=Pass@word
      - ConnectionStrings__HistoryDbConnection=Server=sqldata;Database=history-db;User Id=sa;Password=Pass@word
      - ConnectionStrings__CosmosDb__ServiceEndpoint=https://cosmosdb:8081
      - ConnectionStrings__CosmosDb__AuthKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==
      - ConnectionStrings__Redis=redisdata
      - EventBus__ServiceBusEnabled=false
      - EventBus__RabbitMQ__Connection=rabbitmq
    ports:
      - "5001:80"
      - "5002:443"
    volumes:
      - ~/.aspnet/https:/https:ro

volumes:
  service-rabbit:
    external: false
  service-sqldata:
    external: false
  service-cosmosdbdata:
    external: false
  service-redisdata:
    external: false

And here it's a sample of a dumb test that works only whe set the variable AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE:

[Theory]
[InlineData("https://localhost:8081")]
[InlineData("https://host.docker.internal:8081")]
[InlineData("https://127.0.0.1:8081")]
public async Task TestWithLocalhost(string accountEndpoint)
{
    var cosmosClient = new CosmosClient(
        accountEndpoint,
        "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==",
        new CosmosClientOptions
        {
            SerializerOptions = new CosmosSerializationOptions
            {
                IgnoreNullValues = true,
                Indented = true,
                PropertyNamingPolicy = CosmosPropertyNamingPolicy.CamelCase
            },
            HttpClientFactory = () =>
            {
                HttpMessageHandler httpMessageHandler = new HttpClientHandler()
                {
                    ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator,
                };

                return new HttpClient(httpMessageHandler);
            },
            ConnectionMode = ConnectionMode.Gateway,
        });

        var cancellationToken = new CancellationTokenSource();

        cancellationToken.CancelAfter(TimeSpan.FromSeconds(30));

        var result = await cosmosClient.CreateDatabaseIfNotExistsAsync("UnitTest", cancellationToken: cancellationToken.Token);

        cancellationToken.Dispose();

        result.StatusCode.Should().BeOneOf(HttpStatusCode.Created, HttpStatusCode.OK);
}

Any sugetions on how can I manage this situation? I also tried to Cosmos Db emulator installed on my local machine, but I had the same problem, the integration tests can access but the application can not.

milismsft commented 2 years ago

@MatheusXavier We do not specifically support this scenario. For local testing and development while using Visual Studio and Cosmos DB we strongly recommend to our users to rely on the MSI installation of the Azure Cosmos DB emulator in order to get the best performance while using the emulator.

In your testing you should be able to configure the Cosmos DB endpoint to the emulator's endpoint (started from the MSI installation), just like you might configure your test/application to target an Azure Cosmos DB account hosted in the Azure cloud.