UnknownEndpoint: Inaccessible host: `localhost'. When trying to connect to localhost with express and dynamodb local

Issue

I am using docker compose to create two containers one for dynamodb local and one for nodejs express app.

docker-compose.dev.yml

version: '3'

services:
  dynamodb-local:
    command: "-jar DynamoDBLocal.jar -sharedDb -optimizeDbBeforeStartup -dbPath ./data"
    image: "amazon/dynamodb-local:latest"
    container_name: dynamodb-local
    ports:
      - "8000:8000"
    volumes:
      - "./docker/dynamodb:/home/dynamodblocal/data"
    working_dir: /home/dynamodblocal
    networks:
      - dynamodb-network

  node-app:
    depends_on:
        - dynamodb-local
    container_name: dev-nodejs-backend
    ports:
      - '3000:3000'
    volumes:
      - .:/usr/src/node-app
    environment:
      AWS_ACCESS_KEY_ID: 'DUMMYIDEXAMPLE'
      AWS_SECRET_ACCESS_KEY: 'DUMMYEXAMPLEKEY'
    networks:
      - dynamodb-network
    command: yarn dev -L

networks:
  dynamodb-network:
    driver: bridge

Dockerfile

FROM node:alpine

RUN mkdir -p /usr/src/node-app && chown -R node:node /usr/src/node-app

WORKDIR /usr/src/node-app

COPY package.json yarn.lock ./

USER node

RUN yarn install --pure-lockfile

COPY --chown=node:node . .

EXPOSE 3000

model.js

var AWS = require('aws-sdk');

AWS.config.update({
  accessKeyId: 'YOUR-ACCESSKEYID' ,
  secretAccessKey: 'YOUR-SECRETACCESSKEY' ,
  region: "localhost",
  endpoint: 'http://localhost:8000',
});

const DynamoDB = new AWS.DynamoDB();
var docClient = new AWS.DynamoDB.DocumentClient();

var table = 'URL';

const createTable = async () => {
  var params = {
    TableName : table,
    KeySchema: [
        { AttributeName: "hash", KeyType: "HASH"},  //Partition key
    ],
    AttributeDefinitions: [       
        { AttributeName: "hash", AttributeType: "S" },
    ],
    ProvisionedThroughput: {      
        ReadCapacityUnits: 5, 
        WriteCapacityUnits: 5
    }
};
  const result = await DynamoDB.createTable(params).promise();
  return result;
}

The error on console

UnknownEndpoint: Inaccessible host: `localhost'. This service may not be available in the `localhost' region.
at Request.ENOTFOUND_ERROR (/usr/src/node-app/node_modules/aws-sdk/lib/event_listeners.js:507:46)
at Request.callListeners (/usr/src/node-app/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/usr/src/node-app/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/usr/src/node-app/node_modules/aws-sdk/lib/request.js:688:14)
at ClientRequest.error (/usr/src/node-app/node_modules/aws-sdk/lib/event_listeners.js:339:22)
at ClientRequest.<anonymous> (/usr/src/node-app/node_modules/aws-sdk/lib/http/node.js:96:19)
at ClientRequest.emit (node:events:379:20)
at ClientRequest.EventEmitter.emit (node:domain:470:12)
at Socket.socketErrorListener (node:_http_client:462:9)
at Socket.emit (node:events:379:20)
at Socket.EventEmitter.emit (node:domain:470:12)
at emitErrorNT (node:internal/streams/destroy:188:8)
at emitErrorCloseNT (node:internal/streams/destroy:153:3)
at processTicksAndRejections (node:internal/process/task_queues:81:21) {
code: 'UnknownEndpoint',
region: 'localhost',
hostname: 'localhost',
retryable: true,
originalError: Error: connect ECONNREFUSED 127.0.0.1:8000
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1139:16) {
errno: -111,
code: 'NetworkingError',
syscall: 'connect',
address: '127.0.0.1',
port: 8000,
region: 'localhost',
hostname: 'localhost',
retryable: true,
time: 2021-02-05T14:23:15.559Z
},
time: 2021-02-05T14:23:15.559Z
}

Dynamodb local is running on port 8000, but I am unable to connect it from my express app.
Is there anything I can change in compose file or it is some different error?

Solution

I suspect that your problem is in here:

AWS.config.update({
  accessKeyId: 'YOUR-ACCESSKEYID' ,
  secretAccessKey: 'YOUR-SECRETACCESSKEY' ,
  region: "localhost",
  endpoint: 'http://localhost:8000',
});

When you try to connect to localhost from inside of a container, it will try to connect to localhost from the perspective of that container – which is the container itself.

The container thinks it’s its own separate machine, thus localhost refers to the container itself. This doesn’t work, because DynamoDB is not running inside your node container.

What you want to happen is that the container connects to either port 8000 or the docker host or the dynamodb-local container. Since you’re using a bridge network, the latter should be easy to achieve – set the endpoint to http://dynamodb-local:8000/. Docker should provide your container with DNS-resolution for the names of other containers within its network. I suggest you check out the docs for more on bridge networking.

tl;dr: this might do the trick

AWS.config.update({
  accessKeyId: 'YOUR-ACCESSKEYID' ,
  secretAccessKey: 'YOUR-SECRETACCESSKEY' ,
  region: "localhost",
  endpoint: 'http://dynamodb-local:8000',
});

Answered By – Maurice

Answer Checked By – David Marino (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.