首页 文章

将AWS SAM Local与docker中的dynamodb连接起来

提问于
浏览
6

我已经使用AWS sam本地设置了api gateway / aws lambda对,并确认我可以在运行后成功调用它

sam local start-api

然后我在docker容器中添加了一个本地dynamodb实例,并使用aws cli在其上创建了一个表

但是,将代码添加到lambda以写入我收到的dynamodb实例:

2018-02-22T11:13:16.172Z ed9ab38e-fb54-18a4-0852-db7e5b56c8cd错误:无法写入表:{“message”:“connect ECONNREFUSED 0.0.0.0:8000","code":"NetworkingError” “错误号”: “ECONNREFUSED”, “系统调用”: “连接”, “地址”: “0.0.0.0”, “端口”:8000, “区域”: “欧盟 - 西-2”, “主机名”:” 0.0.0.0“,”retryable“:true,”time“:”2018-02-22T11:13:16.165Z“}从命令写入事件:{”name“:”test“,”geolocation“:”xyz“, “type”:“createDestination”} END RequestId:ed9ab38e-fb54-18a4-0852-db7e5b56c8cd

我在网上看到你可能需要连接到同一个docker网络,所以我创建了一个网络 docker network create lambda-local 并将我的启动命令更改为:

sam local start-api --docker-network lambda-local

docker run -v "$PWD":/dynamodb_local_db -p 8000:8000 --network=lambda-local cnadiminti/dynamodb-local:latest

但仍然收到相同的错误

山姆本地打印 2018/02/22 11:12:51 Connecting container 98b19370ab92f3378ce380e9c840177905a49fc986597fef9ef589e624b4eac3 to network lambda-local

我正在使用以下方法创建dynamodbclient:

const AWS = require('aws-sdk')
const dynamodbURL = process.env.dynamodbURL || 'http://0.0.0.0:8000'
const awsAccessKeyId = process.env.AWS_ACCESS_KEY_ID || '1234567'
const awsAccessKey = process.env.AWS_SECRET_ACCESS_KEY || '7654321'
const awsRegion = process.env.AWS_REGION || 'eu-west-2'

console.log(awsRegion, 'initialising dynamodb in region: ')

let dynamoDbClient
const makeClient = () => {
  dynamoDbClient = new AWS.DynamoDB.DocumentClient({
    endpoint: dynamodbURL,
    accessKeyId: awsAccessKeyId,
    secretAccessKey: awsAccessKey,
    region: awsRegion
  })
  return dynamoDbClient
}

module.exports = {
  connect: () => dynamoDbClient || makeClient()
}

并检查dynamodbclient我的代码正在创建节目

DocumentClient {
  options:
   { endpoint: 'http://0.0.0.0:8000',
     accessKeyId: 'my-key',
     secretAccessKey: 'my-secret',
     region: 'eu-west-2',
     attrValue: 'S8' },
  service:
   Service {
     config:
      Config {
        credentials: [Object],
        credentialProvider: [Object],
        region: 'eu-west-2',
        logger: null,
        apiVersions: {},
        apiVersion: null,
        endpoint: 'http://0.0.0.0:8000',
        httpOptions: [Object],
        maxRetries: undefined,
        maxRedirects: 10,
        paramValidation: true,
        sslEnabled: true,
        s3ForcePathStyle: false,
        s3BucketEndpoint: false,
        s3DisableBodySigning: true,
        computeChecksums: true,
        convertResponseTypes: true,
        correctClockSkew: false,
        customUserAgent: null,
        dynamoDbCrc32: true,
        systemClockOffset: 0,
        signatureVersion: null,
        signatureCache: true,
        retryDelayOptions: {},
        useAccelerateEndpoint: false,
        accessKeyId: 'my-key',
        secretAccessKey: 'my-secret' },
     endpoint:
      Endpoint {
        protocol: 'http:',
        host: '0.0.0.0:8000',
        port: 8000,
        hostname: '0.0.0.0',
        pathname: '/',
        path: '/',
        href: 'http://0.0.0.0:8000/' },
     _clientId: 1 },
  attrValue: 'S8' }

该设置应该有效吗?我如何让他们互相交谈?

----编辑----

基于Twitter对话,值得一提(也许)我可以在CLI和web shell中与dynamodb进行交互

dynamo db at the CLI

dynamodb web shell

3 回答

  • 1

    如果你在很多开发者的mac上使用sam-local,你应该可以使用

    options.endpoint = "http://docker.for.mac.localhost:8000"

    或者在较新的docker https://docs.docker.com/docker-for-mac/release-notes/#docker-community-edition-18030-ce-mac59-2018-03-26上安装

    options.endpoint = "http://host.docker.internal:8000"

    而不是像上面保罗所做的那样做多个命令(但可能更平台无关?) .

  • 5

    正如@Paul所提到的,它是关于在docker容器 - lambda和database之间配置网络 .

    另一种对我有用的方法(使用docker-compose) .

    泊坞窗 - 撰写:

    version: '2.1'
    
    services:
      db:
        image: ...
        ports:
          - "3306:3306"
        networks:
          - my_network
        environment:
          ...
        volumes:
          ...
    
    networks:
      my_network:
    

    然后,在 docker-compose up 之后,运行 docker network ls 将显示:

    NETWORK ID          NAME                        DRIVER              SCOPE
    7eb440d5c0e6        dev_my_network              bridge              local
    

    我的泊坞窗容器名称是 dev_db_1 .

    我的js代码是:

    const connection = mysql.createConnection({
        host: "dev_db_1",
        port: 3306,
        ...
    });
    

    然后,运行 sam 命令:

    sam local invoke --docker-network dev_my_network -e my.json
    

    堆:

    • Docker:18.03.1-ce

    • Docker-compose:1.21.1

    • MacOS HighSierra 10.13.6

  • 6

    非常感谢Heitor Lessa who answered me on Twitter以及回购示例

    这指向了我的答案......

    • dynamodb的docker容器在我的机器上下文中是127.0.0.1(这就是为什么我可以与它交互)

    • SAM本地的docker容器在我的机器上下文中位于127.0.0.1

    • 但它们不是在127.0.0.1彼此的上下文中

    所以:https://github.com/heitorlessa/sam-local-python-hot-reloading/blob/master/users/users.py#L14

    指示我将我的连接代码更改为:

    const AWS = require('aws-sdk')
    const awsRegion = process.env.AWS_REGION || 'eu-west-2'
    
    let dynamoDbClient
    const makeClient = () => {
      const options = {
        region: awsRegion
      }
      if(process.env.AWS_SAM_LOCAL) {
        options.endpoint = 'http://dynamodb:8000'
      }
      dynamoDbClient = new AWS.DynamoDB.DocumentClient(options)
      return dynamoDbClient
    }
    
    module.exports = {
      connect: () => dynamoDbClient || makeClient()
    }
    

    重要的是:

    if(process.env.AWS_SAM_LOCAL) {
      options.endpoint = 'http://dynamodb:8000'
    }
    

    from the context of the SAM local docker container the dynamodb container is exposed via its name

    我的两个启动命令最终为:

    docker run -d -v "$PWD":/dynamodb_local_db -p 8000:8000 --network lambda-local --name dynamodb cnadiminti/dynamodb-local

    AWS_REGION=eu-west-2 sam local start-api --docker-network lambda-local

    唯一的变化就是给dynamodb容器命名

相关问题