2

I have installed dynamodb in a docker container and from the command line I am able to write and read records from it. However, when I try to connect to the database using Python3 I get an error.

Could not connect to the endpoint URL: "http://localhost:8000/": EndpointConnectionError

This is my code snippet

import os
import uuid
import json
import boto3
import traceback
from botocore.exceptions import ClientError

print('Loading function')

region_name = os.environ["REGION_NAME"]
dynamo = boto3.client("dynamodb")
table_name = os.environ["TABLE_NAME"]
musicAlbum_table = boto3.resource("dynamodb", endpoint_url="http://localhost:8000/").Table(table_name)

def respond(err, res=None):
    return {
        'statusCode': '400' if err else '200',
        'body': err.message if err else json.dumps(res),
        'headers': {
            'Content-Type': 'application/json',
        },
    }


def lambda_handler(event, context):

    print("table_name="+ table_name)
    musicAlbum_table.put_item(
                Item={
                    'Artist': 'Joe Satriani',
                    'SongTitle': 'Circles',
                    'AlbumTitle': 'Surfing with an Alien'
                  }
            )
    scan_result = dynamo.scan(TableName=table_name)
    return respond(None, res=scan_result)
user20358
  • 14,182
  • 36
  • 114
  • 186
  • If this is a docker networking issue, the answer is platform dependent. The container that runs the python lambda is probably blocking the network connectivity to localhost. If it is a networking problem it can be solved with solutions on this answer. https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach#24326540. For example, on a mac, I simply change the hostname to 'host.docker.internal' from 'localhost' and my nodejs lambda can connect to a local dynamnodb table running as a java process on the host mac. – starpebble Mar 30 '20 at 01:38
  • this is docker on a windows box – user20358 Mar 31 '20 at 02:51
  • 1
    turns out I only had to change the hostname from localhost to http://host.docker.internal and it connected. – user20358 Mar 31 '20 at 04:12
  • Nice. This is very important, the platform matters. The 'host.docker.internal' is still making its way to Linux though it isn't perfectly available. GitHub Issue: https://github.com/docker/for-linux/issues/264 – starpebble Apr 01 '20 at 04:21

1 Answers1

1

On Mac and Windows with a recent version of Docker, use the hostname 'host.docker.internal' with the http protocol (non-secure) in the boto resource creation. Then, the local lambda running in a container will have network access to the local dynamodb running on the host.

musicAlbum_table =
   boto3.resource("dynamodb",
               endpoint_url="http://host.docker.internal:8000/")
               .Table(table_name)

On Linux it's less easy, maybe wait till v20.04 and wait for the cli command '--add-host host.docker.internal:host-gateway'. I just throw my hands up on Linux.

starpebble
  • 504
  • 3
  • 7