Docker Compose for Amazon DynamoDB with Migration, Seeding, and Admin UI
Beginner guide on how to set up local development for Amazon DynamoDB with migration and seeder without creating a custom program.
Why Amazon DynamoDB?
Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale. It’s a fully managed, multi-region, multi-active, durable database with built-in security, backup and restores, and in-memory caching for internet-scale applications.
The Problem
Since Amazon DynamoDB is a fully managed service, in the past we used to have to connect to a real instance even on the local development process. Nowadays with Docker, we can just spawn a container within our local machine for local development.
The problem arises when we need to create a certain program to create the table or seed the database in our local container. We don’t want to create a custom program to create the table or seed the table. What’s more why waste time when we can do everything with only Docker. We can practically do the same no matter what programming language we’re an expert with.
Prerequisites
- Docker ≥ 20.10.8
- Docker Compose ≥ 1.27.4
Steps
Create a project with this structure:
{21-09-15 22:28}arwego:~/go/src/github.com/rizalgowandy/docker-sample/dynamodb@main% tree
.
├── docker-compose.yaml
└── schema
├── product.json
└── product_seeder.json
Create a migration called product.json file inside /schema to create the product table:
{
"TableName": "product",
"KeySchema": [
{ "AttributeName": "id", "KeyType": "HASH" },
{ "AttributeName": "created_at", "KeyType": "RANGE" }
],
"AttributeDefinitions": [
{ "AttributeName": "id", "AttributeType": "S" },
{ "AttributeName": "created_at", "AttributeType": "S" }
],
"ProvisionedThroughput": {
"ReadCapacityUnits": 10,
"WriteCapacityUnits": 5
}
}
Create a seeding file called product_seeder.json inside /schema to seed the table with two data:
{
"product": [
{
"PutRequest": {
"Item": {
"id": {
"S": "1"
},
"created_at": {
"S": "20210101"
},
"name": {
"S": "gold"
},
"is_deleted": {
"BOOL": false
}
}
}
},
{
"PutRequest": {
"Item": {
"id": {
"S": "2"
},
"created_at": {
"S": "20210101"
},
"name": {
"S": "copper"
},
"is_deleted": {
"BOOL": false
}
}
}
}
]
}
Create a docker-compose file:
version: "3"
services:
dynamodb:
image: amazon/dynamodb-local:1.16.0
container_name: app-dynamodb
hostname: app-dynamodb
volumes:
- app_dynamodb:/home/dynamodblocal
working_dir: /home/dynamodblocal
ports:
- "8000:8000"
command: "-jar DynamoDBLocal.jar -sharedDb -dbPath ."
restart: unless-stopped
dynamodb_admin:
image: aaronshaf/dynamodb-admin:dependabot_npm_and_yarn_aws-sdk-2.952.0
container_name: app-dynamodb_admin
ports:
- "8001:8001"
environment:
- DYNAMO_ENDPOINT=http://dynamodb:8000
depends_on:
- dynamodb
restart: unless-stopped
dynamodb_migrator:
image: banst/awscli:1.18.76
container_name: app-dynamodb_migrator
working_dir: /home/dynamodblocal
command: dynamodb create-table --cli-input-json file://product.json --endpoint-url http://dynamodb:8000
volumes:
- ./schema:/home/dynamodblocal
environment:
- AWS_ACCESS_KEY_ID=unicorn_user
- AWS_SECRET_ACCESS_KEY=magical_password
- AWS_DEFAULT_REGION=ap-southeast-1
depends_on:
- dynamodb
dynamodb_seeder:
image: banst/awscli:1.18.76
container_name: app-dynamodb_seeder
working_dir: /home/dynamodblocal
command: dynamodb batch-write-item --request-items file://product_seeder.json --endpoint-url http://dynamodb:8000
volumes:
- ./schema:/home/dynamodblocal
environment:
- AWS_ACCESS_KEY_ID=unicorn_user
- AWS_SECRET_ACCESS_KEY=magical_password
- AWS_DEFAULT_REGION=ap-southeast-1
depends_on:
- dynamodb_migrator
- dynamodb
restart: on-failure
volumes:
app_dynamodb:
driver: local
Important information from the docker-compose file:
- Amazon DynamoDB is running at port 8000.
- Admin UI is running at port 8001.
- AWS CLI for migration and seeding is pointing to port 8000 aka our Amazon DynamoDB port.
- Migration will create a product table and seed it with two data using /schema/product.json and /schema/product_seeder.json.
Then execute:
$ docker-compose up
Go to http://localhost:8001/ to see the admin UI.
The table has been created, and inside you can see it’s already filled with our seeding data.
Voilà, and we are done. Now your local development with Amazon DynamoDB just got a lot simpler. You can create a table, seed the table, and even control everything with an admin UI.
References:
- Source: https://github.com/rizalgowandy/docker-sample
- Amazon DynamoDB Local: https://registry.hub.docker.com/r/amazon/dynamodb-local
- UI: https://registry.hub.docker.com/r/aaronshaf/dynamodb-admin
- AWS CLI for Migration and Seeding: https://registry.hub.docker.com/r/banst/awscli