9
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

DynamoDBローカルのDockerコンテナにsharedDBオプションを付与する

別の記事でDynamoDB LocalをDockerコンテナで起動させましたが、公式のDockerイメージを利用する場合はアクセスキーID/リージョンごとにデータベースファイルが分離されてしまいます(AWS CLIでDynamoDBにテーブルを定義したはいいが、Pythonアプリから接続したらテーブルが存在しない...など)。異なるアプリでも同一のデータベースファイルにアクセスする場合はsharedDBオプションを指定してDynamoDBローカルを起動させる必要があるようです。
DynamoDBローカルのDockerイメージをカスタマイズし、sharedDBオプションを付与してコンテナを起動させてみたいと思います。

DynamoDBローカルの注意事項

DynamoDBローカルにおけるデータベースファイルの扱いは、公式サイトの注意事項(*1)に記述があります。sharedDBオプションを指定しなかった場合、データベースファイル名はアクセスキーIDとリージョン名が使用されmyaccesskeyid_region.dbファイルにデータが格納されます。
アプリでアクセスキーIDを与えていない場合、色々と面倒なことが生じます。(前述のとおりAWS CLIでDynamoDBにテーブルを定義したはいいが、Pythonアプリから接続したらテーブルが存在しない...など。アプリから接続する際は通常IAMロールを使いアクセスキーIDを利用することはあまりないでしょうしね...。IAMロールが使えない環境では~/.aws/credentialsが認証情報として使われるのでそこにアクセスキーIDを書けば良いようですが。)

DynamoDBローカルの起動オプション

公式のDynamoDBローカルのDockerイメージ情報を確認すると、コンテナ起動時に以下が実行されるようになっています。ここにsharedDBオプションを追加すれば、単一のデータベースファイルでDynamoDBローカルを起動させることができるようになります。

java -jar DynamoDBLocal.jar -inMemory

公式のDynamoDBローカルのイメージ情報はdocker inspectで確認します。参考記事(*2)にもあるとおり、Entrypointは[java]でCmdは[-jar DynamoDBLocal.jar -inMemory]で起動しています。Cmdを[-jar DynamoDBLocal.jar -inMemory -sharedDB]に変更すれば対応できます。

docker inspect amazon/dynamodb-local

イメージのカスタマイズ

Dockerfileを作成し、docker buildを行います。

以下のDockerfileを作成します。(inMemoryはファイルではなくメモリ上にデータを保持するのでコンテナが停止するとデータが削除されます。ファイルへの保管が必要な場合はオプションを外します)

from amazon/dynamodb-local

ENTRYPOINT ["java"]
CMD ["-jar", "DynamoDBLocal.jar", "-inMemory", "-sharedDb"]

Dockerfileを作成したら、Dockerイメージをビルドします。

docker build -t my-dynamodb-local --no-cache=true .

作成してDockerイメージを起動しオプションを確認します。(バックグラウンドで起動したい場合は-dを追加)

docker run -it -p 8000:8000 --name dynamodb_local my-dynamodb-local 
  Initializing DynamoDB Local with the following configuration:
   Port:  8000
   InMemory:  true
   DbPath:    null
   SharedDb:  true
   shouldDelayTransientStatuses:  false
   CorsParams:    *

Pythonアプリからの接続

Pythonの場合、以下のコードで接続します。事前にboto3をpipでインストールしておきます。
開発の際はDynamoDBローカルを利用し、ステージングや本番に切り替える際にエンドポイントを変更(もしくはエンドポイントを指定しない)してDynamoDB Webサービスに接続すれば良いのかなと思います。DynamoDBのエンドポイントはこちらを参照。

import boto3

endpoint_url = 'http://localhost:8000'
dynamodb = boto3.resource('dynamodb', endpoint_url=endpoint_url)

参考記事

*1 DynamoDB 使用に関する注意事項
*2 DynamoDB LocalのDockerイメージを触ってみる

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
9
Help us understand the problem. What are the problem?