Search code examples
amazon-web-servicesdockerdocker-composeamazon-dynamodbamazon-dynamodb-local

Create DynamoDB table in Docker Compose


I'm using Docker Compose for testing to replicate my AWS infrastructure which uses CloudFormation. My CloudFormation template create a FooBars DynamoDB table and I want to do the same for my Docker Compose setup.

I add a DynamoDB Local service:

  foobar-service-db:
    image: amazon/dynamodb-local:latest
    command: "-jar DynamoDBLocal.jar -inMemory"
    ports: [8090:8000]
    restart: always

When I run docker compose … I can then use aws dynamodb create-table to create a table using --endpoint-url http://localhost:8090 and --region dummy-region. Great. I want to do that as part of Docker Compose, so I add this "service":

  foobar-service-db-init:
    depends_on:
      - foobar-service-db
    image: amazon/aws-cli
    environment:
      AWS_ACCESS_KEY_ID: dummy-key-id
      AWS_SECRET_ACCESS_KEY: dummy-key
    command: >-
      dynamodb create-table
          --table-name FooBars
          --attribute-definitions
              AttributeName=id,AttributeType=S
          --key-schema
              AttributeName=id,KeyType=HASH
          --billing-mode PAY_PER_REQUEST
          --endpoint-url http://foobar-service-db:8000 --region dummy-region

(Note that I have to indicate the container port instead of the host port, because the request is inside the Docker Compose network.)

I can see the output when Docker Compose starts up, and it shows that a table with an ARN of arn:aws:dynamodb:ddblocal:000000000000:table/FooBars was created. But when I try aws dynamodb list-tables --endpoint-url http://localhost:8090 --region dummy-region from the command line, no tables are listed.

However on the command line I can create the table using aws dynamodb create-table … --endpoint-url http://localhost:8090 --region dummy-region, which should be equivalent what foobar-service-db-init is calling. This command also says is created a table with ARN arn:aws:dynamodb:ddblocal:000000000000:table/FooBars was created. And if I run the same command again, it says "Cannot create preexisting table" as expected.

So foobar-service-db-init inside Docker Compose seems to be creating the table somewhere else, where it doesn't show up when I make the request from the command line. But where else could it be creating it? There is only one DynamoDB Local service, foobar-service-db!

(From the command line I'm using my actual AWS credentials. But that shouldn't make a difference. Surely DynamoDB Local doesn't have a separate namespace based on user identity—that's not how it works on AWS itself. The namespace is based on region, and I specify the same dummy-region.)


Solution

  • Try using -sharedDb:

    command: "-jar DynamoDBLocal.jar -inMemory -sharedDb"
    
    • If you use the -sharedDb option, DynamoDB creates a single database file named shared-local-instance.db. Every program that connects to DynamoDB accesses this file. If you delete the file, you lose any data that you have stored in it.

    • If you omit -sharedDb, the database file is named myaccesskeyid_region.db, with the AWS access key ID and AWS Region as they appear in your application configuration. If you delete the file, you lose any data that you have stored in it.