DynamoDBローカルのDockerコンテナにsharedDBオプションを付与する
DynamoDBローカルのDockerコンテナにsharedDBオプションを付与する:
別の記事でDynamoDB LocalをDockerコンテナで起動させましたが、公式のDockerイメージを利用する場合はアクセスキーID/リージョンごとにデータベースファイルが分離されてしまいます(AWS CLIでDynamoDBにテーブルを定義したはいいが、Pythonアプリから接続したらテーブルが存在しない...など)。異なるアプリでも同一のデータベースファイルにアクセスする場合はsharedDBオプションを指定してDynamoDBローカルを起動させる必要があるようです。
DynamoDBローカルのDockerイメージをカスタマイズし、sharedDBオプションを付与してコンテナを起動させてみたいと思います。
DynamoDBローカルにおけるデータベースファイルの扱いは、公式サイトの注意事項(*1)に記述があります。sharedDBオプションを指定しなかった場合、データベースファイル名はアクセスキーIDとリージョン名が使用されmyaccesskeyid_region.dbファイルにデータが格納されます。
アプリでアクセスキーIDを与えていない場合、色々と面倒なことが生じます。(前述のとおりAWS CLIでDynamoDBにテーブルを定義したはいいが、Pythonアプリから接続したらテーブルが存在しない...など。アプリから接続する際は通常IAMロールを使いアクセスキーIDを利用することはあまりないでしょうしね...。IAMロールが使えない環境では~/.aws/credentialsが認証情報として使われるのでそこにアクセスキーIDを書けば良いようですが。)
公式のDynamoDBローカルのDockerイメージ情報を確認すると、コンテナ起動時に以下が実行されるようになっています。ここにsharedDBオプションを追加すれば、単一のデータベースファイルでDynamoDBローカルを起動させることができるようになります。
公式のDynamoDBローカルのイメージ情報はdocker inspectで確認します。参考記事(*2)にもあるとおり、Entrypointは[java]でCmdは[-jar DynamoDBLocal.jar -inMemory]で起動しています。Cmdを[-jar DynamoDBLocal.jar -inMemory -sharedDB]に変更すれば対応できます。
Dockerfileを作成し、docker buildを行います。
以下のDockerfileを作成します。(inMemoryはファイルではなくメモリ上にデータを保持するのでコンテナが停止するとデータが削除されます。ファイルへの保管が必要な場合はオプションを外します)
Dockerfileを作成したら、Dockerイメージをビルドします。
作成してDockerイメージを起動しオプションを確認します。(バックグラウンドで起動したい場合は-dを追加)
Pythonの場合、以下のコードで接続します。事前にboto3をpipでインストールしておきます。
開発の際はDynamoDBローカルを利用し、ステージングや本番に切り替える際にエンドポイントを変更(もしくはエンドポイントを指定しない)してDynamoDB Webサービスに接続すれば良いのかなと思います。DynamoDBのエンドポイントはこちらを参照。
*1 DynamoDB 使用に関する注意事項
*2 DynamoDB LocalのDockerイメージを触ってみる
別の記事で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
docker inspect amazon/dynamodb-local
イメージのカスタマイズ
Dockerfileを作成し、docker buildを行います。以下のDockerfileを作成します。(inMemoryはファイルではなくメモリ上にデータを保持するのでコンテナが停止するとデータが削除されます。ファイルへの保管が必要な場合はオプションを外します)
from amazon/dynamodb-local ENTRYPOINT ["java"] CMD ["-jar", "DynamoDBLocal.jar", "-inMemory", "-sharedDb"]
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)
参考記事
*1 DynamoDB 使用に関する注意事項*2 DynamoDB LocalのDockerイメージを触ってみる
コメント
コメントを投稿