0

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.)

Garret Wilson
  • 18,219
  • 30
  • 144
  • 272

1 Answers1

1

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.

Leeroy Hannigan
  • 11,409
  • 3
  • 14
  • 31
  • Unbelievable—that was it! According to the [DynamoDB local usage notes](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.UsageNotes.html), if you use `-inMemory`, DynamoDB Local doesn't write any database file at all. And in fact it says, "Unless you're using the `-sharedDb` or the `-inMemory` option, DynamoDB uses these [access key and region] values to name the local database file." But apparently even with the `-inMemory` option DynamoDB Local _still makes separate namespaces_ based on the access key! Thank you for the tip! I almost didn't believe you at first. – Garret Wilson Jun 12 '23 at 14:58
  • I've been there before. I'll also get the docs updated to reflect this. – Leeroy Hannigan Jun 12 '23 at 15:14