Home > Software design >  .NET Core service can't access dynamodb-local when both are ran from docker-compose
.NET Core service can't access dynamodb-local when both are ran from docker-compose

Time:09-28

I am building a rest service in .NET Core 6 in Visual Studio 2022. This service is using dynamodb for its database. I am running both of these inside Docker with a single docker-compose file.

If I startup dynamodb-local in it's own docker-compose file like this

version: '3.4'

services:

  dynamodb-local:
    image: amazon/dynamodb-local:latest
    container_name: dynamodb-local    
    command: "-jar DynamoDBLocal.jar -sharedDb"
    ports:
      - "8000:8000"

I configure the client in the Program.cs like this

var clientConfig = new AmazonDynamoDBConfig {ServiceURL = "http://localhost:8000" };
builder.Services.AddSingleton<IAmazonDynamoDB>(_ => new AmazonDynamoDBClient(clientConfig));

If I run the service from IIS Express, everything works perfectly.

However, I enabled containerization for the project and want to run everything together inside docker. When I do this my, my docker-compose looks like this:

version: '3.4'

services:

  dynamodb-local:
    image: amazon/dynamodb-local:latest    
    container_name: dynamodb-local    
    command: "-jar DynamoDBLocal.jar -sharedDb"
    ports:
      - "8000:8000"    
    
  api:
    image: ${DOCKER_REGISTRY-}api    
    container_name: insurance-service    
    build:
      context: .
      dockerfile: src/Api/Dockerfile        
    depends_on:
      - dynamodb-local

Then my docker-compose-override.yml looks like this (this was generated by VS):

version: '3.4'

services:
  api:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https:// :443;http:// :80
    ports:
      - "80"
      - "443"
    volumes:
      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
      - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro

enter image description here

When I start this up using docker-compose inside VS 2022, everything loads up fine. But when I go to save a record to the database this error is thrown:

Amazon.Runtime.AmazonServiceException: Unable to get IAM security credentials from EC2 Instance Metadata Service.

It's like the client registering is trying to access localhost:8000 but there seems to be nothing there so it defaults back to EC2 IAM Security Creds. I think this is being caused by some weird networking between the 2 services that I don't realize. Like API can't access dynamodb-local with referencing localhost.

Edit: I have also tried throwing arbitrary basic creds in there like this:

var clientConfig = new AmazonDynamoDBConfig { ServiceURL = "http://localhost:8000" };
var creds = new BasicAWSCredentials("xxx", "xxx");
builder.Services.AddSingleton<IAmazonDynamoDB>(_ => new AmazonDynamoDBClient(creds, clientConfig));

This doesn't give me the IAM issue but keeps trying in an infinite loop like it's waiting for localhost to become available and it isn't.

CodePudding user response:

Why don't you try using networking between containers? You can create a network and then access the DynamoDB using the container name, this way the DynamoDB container is accessible internally.

version: '3.4'

services:

  dynamodb-local:
    image: amazon/dynamodb-local:latest    
    container_name: dynamodb-local    
    command: "-jar DynamoDBLocal.jar -sharedDb"
    ports:
      - "8000:8000"    
    
  api:
    image: ${DOCKER_REGISTRY-}api    
    container_name: insurance-service    
    build:
      context: .
      dockerfile: src/Api/Dockerfile        
    depends_on:
      - dynamodb-local
networks:
  default:
    external:
      name: dynamodb-api

And your can replace the URL with the container name like this:

var clientConfig = new AmazonDynamoDBConfig { ServiceURL = "dynamodb-local" };
var creds = new BasicAWSCredentials("xxx", "xxx");
builder.Services.AddSingleton<IAmazonDynamoDB>(_ => new AmazonDynamoDBClient(creds, clientConfig));

You will also have to create a docker network with this command

docker network create dynamodb-api

Hope this helps!

  • Related