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
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!