如何修改Docker Compose实现本地单节点MongoDB事务?
如何修改Docker Compose配置以支持MongoDB单节点副本集事务
问题背景
本地开发的Web应用使用Docker Compose部署MongoDB单实例,需要使用事务时触发错误:
Transaction numbers are only allowed on a replica set member or mongos
配置单节点副本集后,又出现NamespaceNotFound错误,提示Collection [local.oplog.rs] not found,这是因为副本集初始化配置有误。
修改后的完整Docker Compose配置
services: auth-terrai: image: auth-app build: context: .. dockerfile: docker/Dockerfile command: air -c .air.toml volumes: - ../:/app - ../:/go/src/gitlab.com/main/server ports: - 8080:80 - 10000:2345 environment: - VERSION=0.0.1 - TITLE= App - DESCRIPTION= - ENVIRONMENT=dev - HOST=localhost:8080 - WHITE_LIST=./key/white_list.json - FIREBASE_SERVICE_ACCOUNT=./key/service_account.json # 修改为副本集连接字符串,指定replicaSet参数 - MONGO_URL=mongodb://abc123:abc123@urt-mongo-db:27017/?replicaSet=rs0 - MONGODB_NAME=auth networks: - urt-guane # 依赖MongoDB服务,确保先启动MongoDB并完成初始化 depends_on: urt-mongo-db: condition: service_healthy urt-mongo-db: image: mongo # 启动命令:启用副本集,绑定所有IP command: ["--replSet", "rs0", "--bind_ip_all", "--port", "27017"] environment: MONGO_INITDB_ROOT_USERNAME: abc123 MONGO_INITDB_ROOT_PASSWORD: abc123 MONGO_INITDB_DATABASE: auth MONGO_INITDB_REPLICA_SET_NAME: rs0 ports: - 27017:27017 healthcheck: # 使用Docker服务名初始化副本集,同时带上认证信息 test: > echo "try { rs.status() } catch (err) { rs.initiate({_id:'rs0', members:[{_id:0, host:'urt-mongo-db:27017'}]}) }" | mongo -u abc123 -p abc123 --port 27017 --quiet interval: 5s timeout: 30s start_period: 0s retries: 30 volumes: - urt-mongo-db:/data/db # 若需保留keyfile,必须确保文件权限为600,否则MongoDB启动失败 # - ./mongodb-keyfile:/etc/mongo/mongodb-keyfile:ro networks: - urt-guane volumes: urt-mongo-db: external: true networks: urt-guane: external: true
关键修改说明
- 连接字符串更新:应用的
MONGO_URL添加?replicaSet=rs0,明确告知驱动这是副本集连接。 - 副本集节点地址修正:健康检查中使用Docker服务名
urt-mongo-db:27017作为节点地址,而非host.docker.internal,确保容器内部能正确识别节点,避免oplog集合创建失败。 - 健康检查加认证:初始化副本集时带上用户名和密码,适配MongoDB的认证配置,避免无权限操作。
- 服务依赖配置:给应用添加
depends_on规则,等待MongoDB健康检查通过后再启动,避免应用连接时副本集未完成初始化。 - 简化keyfile配置:测试环境单节点副本集可暂时去掉keyfile(无需集群间加密),若保留需确保
mongodb-keyfile文件权限为600。
错误原因解析
之前的配置中,副本集初始化使用了host.docker.internal:27017作为节点地址,导致MongoDB在容器内部无法正确解析该节点,进而无法创建local.oplog.rs集合,触发NamespaceNotFound错误。修改为Docker服务名后,容器能正确识别节点,完成副本集初始化,oplog集合自动创建,事务功能即可正常使用。
内容的提问来源于stack exchange,提问作者Diego L
相关产品推荐
相关产品推荐

