状況
ホスト側のターミナルから見た、DynamoDb LocalのURLは、http://localhost:5003です。
ホスト側のターミナルで、aws dynamodbコマンドを使って、create-table、put-item、get-itemしました。問題ありません。
別のDockerコンテナでwebサーバを走らせています。そのwebサーバから見た、DynamoDb LocalのURLは、http://dynamodb.container:8000です。
そのWebサーバから、DynamoDB LocalへgetItemしたところ、テーブルがないよ、とエラーになってしまいました。
Error executing "GetItem" on "http://dynamodb.container:8000"; AWS HTTP error: Client error: POST http://dynamodb.container:8000 resulted in a 400 Bad Request response: {"__type":"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException","message":"Cannot do operations on a non-existent (truncated…) ResourceNotFoundException (client): Cannot do operations on a non-existent table - {"__type":"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException","message":"Cannot do operations on a non-existent table"}
Code language: JavaScript (javascript)
解決方法
ホスト側のターミナルで作業するときのAWS_ACCESS_KEY_IDとリージョン、Dockerコンテナのwebサーバに渡すAWS_ACCESS_KEY_IDとリージョンを同じにします。
ホスト側のターミナル
Dynamo DB LocalのAWS_ACCESS_KEY_IDとリージョンは任意です。仮に、次のようにします。
AWS_ACCESS_KEY_ID=hoge
リージョン=local
任意なので、リージョン=ap-northeast-1 にしても問題ありません。
ホスト側のターミナルでaws dynamodbコマンドを打つ前に、AWS_ACCESS_KEY_IDを設定します。
$ export AWS_ACCESS_KEY_ID=hoge
$ export AWS_SECRET_ACCESS_KEY=hogehoge
Code language: JavaScript (javascript)
Dynamo DB Localへaws dynamodbコマンドを打つとき、--region オプションでリージョンを指定します。
$ aws dynamodb
--region local
--endpoint-url http://localhost:5003
--table-name myapp_mytable
〜省略〜
Code language: JavaScript (javascript)
Dockerコンテナのwebサーバ側
Dockerコンテナに渡すための環境変数の設定ファイルを作ります。ファイル名は、web.envとします。
AWS_ACCESS_KEY_ID=hoge
AWS_SECRET_ACCESS_KEY=secret
docker-compose.ymlでenv_fileを記述します。
web:
env_file:
- ./web.env
PHPの場合、AwsSdkコンストラクタで、'region'を'local'にします。
$sdk = new AwsSdk([
'endpoint' => 'http://dynamodb.container:8000',
'region' => 'local',
'version' => 'latest'
]);
Code language: PHP (php)
DynamoDB Localのデータファイル
docker-compose.ymlで、Dockerコンテナを停止してもデータが消えないように、dbPathを設定し、Dockerコンテナの/home/dynamodblocal/dataをホスト側のディレクトリに外部マウントしました。
dynamodb:
tty: true
container_name: dynamodb.container
image: amazon/dynamodb-local
ports:
- 5003:8000
command: -jar DynamoDBLocal.jar -dbPath ./data
volumes:
- ./dynamodb/data:/home/dynamodblocal/data
Code language: JavaScript (javascript)
すると、ローカルの ./dynamo/data/ 下に、DynamoDB Localのデータファイルが見えるようになります。
いろいろ試したので、いくつかのファイルができています。
$ ls -1 ./dynamodb/data
AK******************_ap-northeast-1.db
AK******************_local.db
hoge_ap-northeast-1.db
hoge_local.db
つまり、[AWSアカウントID]_[リージョン].db で、分かれて保存されるんですね。
ターミナルから、AWS_ACCESS_KEY_ID=AK****、リージョン=ap-northeast-1で、テーブル作成すると、AK****_ap-northeast-1.db が作られます。
Dockerコンテナのwebサーバから、AWS_ACCESS_KEY_ID=hoge、リージョン=localで、getItemすると、hoge_local.db を読もうとします。
そのため、テーブルがないよ、とエラーになったんですね。