別の記事で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イメージを触ってみる