Docker部署本地DynamoDB报错:无法打开数据库文件
问题:Docker运行DynamoDB本地版时SQLite数据库无法打开报错
运行DynamoDB本地版容器并使用Docker卷持久化数据,创建第一个表时重复出现以下报错,最终脚本执行失败:
dynamodb-local | Aug 31, 2022 3:32:49 PM com.almworks.sqlite4java.Internal log dynamodb-local | WARNING: [sqlite] SQLiteQueue[shared-local-instance.db]: stopped abnormally, reincarnating in 3000ms dynamodb-local | Aug 31, 2022 3:32:52 PM com.almworks.sqlite4java.Internal log dynamodb-local | WARNING: [sqlite] cannot open DB[5]: com.almworks.sqlite4java.SQLiteException: [14] unable to open database file dynamodb-local | Aug 31, 2022 3:32:52 PM com.almworks.sqlite4java.Internal log dynamodb-local | SEVERE: [sqlite] SQLiteQueue[shared-local-instance.db]: error running job queue dynamodb-local | com.almworks.sqlite4java.SQLiteException: [14] unable to open database file dynamodb-local | at com.almworks.sqlite4java.SQLiteConnection.open0(SQLiteConnection.java:1480) dynamodb-local | at com.almworks.sqlite4java.SQLiteConnection.open(SQLiteConnection.java:282) dynamodb-local | at com.almworks.sqlite4java.SQLiteConnection.open(SQLiteConnection.java:293) dynamodb-local | at com.almworks.sqlite4java.SQLiteQueue.openConnection(SQLiteQueue.java:464) dynamodb-local | at com.almworks.sqlite4java.SQLiteQueue.queueFunction(SQLiteQueue.java:641) dynamodb-local | at com.almworks.sqlite4java.SQLiteQueue.runQueue(SQLiteQueue.java:623) dynamodb-local | at com.almworks.sqlite4java.SQLiteQueue.access$000(SQLiteQueue.java:77) dynamodb-local | at com.almworks.sqlite4java.SQLiteQueue$1.run(SQLiteQueue.java:205) dynamodb-local | at java.lang.Thread.run(Thread.java:750)
使用的docker-compose.yml内容如下:
version: "3.9" # optional since v1.27.0 services: server: build: context: ./server/ dockerfile: Dockerfile.consumer ports: - "5558:5558" depends_on: - "dynamodb-local" environment: AWS_ACCESS_KEY_ID: 'DUMMYIDEXAMPLE' AWS_SECRET_ACCESS_KEY: 'DUMMYEXAMPLEKEY' dynamodb-local: image: "amazon/dynamodb-local:latest" ports: - "8000:8000" volumes: - "data:/home/dynamodblocal/data" command: "-jar DynamoDBLocal.jar -sharedDb -dbPath ./data" container_name: dynamodb-local working_dir: /home/dynamodblocal volumes: logvolume01: {} data: {}
创建表的Python代码:
import boto3 from pprint import pprint from botocore.exceptions import ClientError TABLE_NAME = "check_tbl" dynamodb = boto3.client( 'dynamodb', region_name="us-east-1", aws_access_key_id="dummy_access_key", aws_secret_access_key="dummy_secret_key", endpoint_url="http://localhost:8000", ) try: response = dynamodb.describe_table(TableName=TABLE_NAME) except ClientError as ce: if ce.response['Error']['Code'] == 'ResourceNotFoundException': result = dynamodb.create_table( TableName=TABLE_NAME, KeySchema=[ { 'AttributeName': 'id', 'KeyType': 'HASH' # Partition key } ], AttributeDefinitions=[ { 'AttributeName': 'timestamp', 'AttributeType': 'D' } ], ProvisionedThroughput={ 'ReadCapacityUnits': 10, 'WriteCapacityUnits': 10 } ) else: print("Unknown exception occurred while querying for the " + TABLE_NAME + " table. Printing full error:") pprint(ce.response)
注:Docker卷路径/var/lib/docker/volumes/data属主为root,但用户认为此非问题根源。
解决方案
1. 解决容器权限问题
DynamoDB本地版容器默认以非root用户运行(通常是nobody),而Docker匿名卷的默认属主为root,导致进程无法写入数据库文件。可通过以下两种方式解决:
方式一:临时切换为root用户运行容器
修改docker-compose.yml中dynamodb-local服务的配置,添加user: root:
dynamodb-local: image: "amazon/dynamodb-local:latest" ports: - "8000:8000" volumes: - "data:/home/dynamodblocal/data" command: "-jar DynamoDBLocal.jar -sharedDb -dbPath ./data" container_name: dynamodb-local working_dir: /home/dynamodblocal user: root # 添加此行
方式二:使用本地目录绑定并设置权限
在主机创建本地目录,调整权限后绑定到容器:
# 创建本地目录 mkdir -p ./dynamodb-data # 设置权限,允许容器进程写入 chmod 777 ./dynamodb-data
修改docker-compose.yml中的卷配置:
dynamodb-local: # 其他配置不变 volumes: - ./dynamodb-data:/home/dynamodblocal/data # 替换原匿名卷配置
2. 修正创建表的代码错误
当前代码中KeySchema指定了id作为分区键,但AttributeDefinitions中未声明该属性的类型,这会导致创建表请求直接失败。需补充id的属性定义:
result = dynamodb.create_table( TableName=TABLE_NAME, KeySchema=[ { 'AttributeName': 'id', 'KeyType': 'HASH' # Partition key } ], AttributeDefinitions=[ { 'AttributeName': 'id', 'AttributeType': 'S' # 根据实际业务需求调整类型,如S=字符串、N=数字等 }, { 'AttributeName': 'timestamp', 'AttributeType': 'D' } ], ProvisionedThroughput={ 'ReadCapacityUnits': 10, 'WriteCapacityUnits': 10 } )
内容的提问来源于stack exchange,提问作者Brian
相关产品推荐
相关产品推荐

