Docker部署MongoDB后Python连接认证失败求助
我用Docker创建了MongoDB实例,但连接后无法修改数据库内容,认证一直失败。以下是我的Docker启动命令:
# Start the docker container echo "mongodb password in file" $(pwd)/mongodb.pass docker run \ -p 27017:27017 \ --restart unless-stopped \ --name mongodb \ -v airlist:/data/db \ -v $(pwd)/mongodb.pass:/mongodb.pass \ -d \ --network airfetch \ -e MONGO_INITDB_ROOT_USERNAME=airfetch \ -e MONGO_INITDB_ROOT_PASSWORD=airlist27101978 \ mongo:latest
在宿主机上运行Python脚本尝试连接:
import pymongo import urllib.parse username = urllib.parse.quote_plus('airfetch') password = urllib.parse.quote_plus('airlist27101978') auth_db = 'admin' auth_source='?authSource=admin&retryWrites=true&w=majority' auth_string = f"mongodb://{username}:{password}@localhost:27017/{auth_db}{auth_source}" myclient = pymongo.MongoClient(auth_string)
执行后报错:
pymongo.errors.OperationFailure: Authentication failed., full error: {'ok': 0.0, 'errmsg': 'Authentication failed.', 'code': 18, 'codeName': 'AuthenticationFailed'}
另外,仅用auth_string=mongodb://localhost:27017时,server_info能返回响应,但无法插入记录或创建数据库。
排查步骤与解决方案
1. 修正连接字符串格式
你的连接字符串拼接存在格式错误:将auth_db(admin)直接放在端口后,又重复添加?authSource=admin,导致URL解析异常。推荐两种正确写法:
# 写法1:默认连接admin库,参数中指定重试策略(authSource可省略,默认就是admin) auth_string = f"mongodb://{username}:{password}@localhost:27017/admin?retryWrites=true&w=majority" # 写法2:不指定默认库,明确指定认证源为admin auth_string = f"mongodb://{username}:{password}@localhost:27017/?authSource=admin&retryWrites=true&w=majority"
2. 验证容器内用户是否正常创建
进入MongoDB容器,手动测试用户认证:
docker exec -it mongodb mongosh -u airfetch -p airlist27101978 --authenticationDatabase admin
如果能成功进入MongoDB Shell,说明用户创建正常;如果失败,需重置容器与数据卷(注意备份数据):
docker stop mongodb docker rm mongodb docker volume rm airlist
之后重新运行容器,确保MONGO_INITDB_ROOT_USERNAME和MONGO_INITDB_ROOT_PASSWORD环境变量正确传递。
3. 确认密码转义是否正确
虽然使用了urllib.parse.quote_plus,但可以打印转义后的密码验证:
print(password)
确保转义后的字符串与实际密码完全匹配,无遗漏或错误转义。
4. 检查MongoDB绑定地址
默认MongoDB容器绑定0.0.0.0,但如果配置被修改,可能仅绑定容器内部地址。进入容器查看配置:
docker exec -it mongodb cat /etc/mongod.conf.orig | grep bindIp
如果输出是bindIp: 127.0.0.1,启动容器时需添加--bind_ip_all参数:
docker run \ # 保留原有参数 mongo:latest --bind_ip_all
5. 理解无认证连接的权限限制
用mongodb://localhost:27017连接时,能获取server_info但无法操作数据库是正常现象——此时处于无认证状态,MongoDB仅提供基础连接响应,没有数据操作权限,说明认证机制已正常开启。
内容的提问来源于stack exchange,提问作者Dronakuul

