我正在开发一个在连接到 MongoDB 的 Docker 容器中运行的 Flask 应用程序,该应用程序也在一个单独的容器中运行。一切都启动,没有任何错误,并且 MongoDB 连接已成功建立,如日志所示。但是,当我执行用户注册等操作时,MongoDB 数据库中没有出现新数据。
容器正在运行和通信,没有错误,并且我已确保 MongoDB 用户具有必要的权限。附上所有必要的文件
环境: 蟒蛇:3.9 MongoDB:4.0.8 Docker:使用 Docker Compose 运行
Dockerfile ->
FROM python:3.9-slim
WORKDIR /app
RUN apt-get update && apt-get install -y \
build-essential \
python3-dev \
&& rm -rf /var/lib/apt/lists/*
COPY req.txt .
RUN pip install --no-cache-dir -r req.txt
RUN pip install gunicorn
COPY . .
RUN mkdir -p logs
RUN useradd -m appuser && chown -R appuser:appuser /app
USER appuser
EXPOSE 5001
CMD ["gunicorn", "--bind", "0.0.0.0:5001", "--workers", "4", "--timeout", "120", "app:app"]
docer 撰写 ->
version: '3'
services:
flask:
build:
context: .
dockerfile: Dockerfile
image: <my-flask-image>:latest
deploy:
replicas: 3
ports:
- "6001-6003:5001"
environment:
MONGO_URI: mongodb://<my-username>:<my-password>@mongodb:27017/<my-db>?authSource=admin
APP_ENV: "prod"
APP_DEBUG: "False"
APP_PORT: 5001
volumes:
- ./logs:/app/logs
depends_on:
- mongodb
networks:
- backend
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
mongodb:
image: mongo:4.0.8
container_name: mongodb
restart: unless-stopped
ports:
- "27017:27017"
command: mongod --auth
environment:
MONGO_INITDB_ROOT_USERNAME: <my-username>
MONGO_INITDB_ROOT_PASSWORD: <my-password>
MONGO_INITDB_DATABASE: admin
volumes:
- mongodbdata:/data/db
- ./init.js:/docker-entrypoint-initdb.d/init-mongo.js
networks:
- backend
networks:
backend:
driver: bridge
volumes:
mongodbdata:
driver: local
MongoDB 初始化脚本 (init-mongo.js) ->
db = db.getSiblingDB('admin');
db.createUser({
user: '<my-username>',
pwd: '<my-password>',
roles: [
{ role: 'userAdminAnyDatabase', db: 'admin' },
{ role: 'readWriteAnyDatabase', db: 'admin' },
{ role: 'dbAdminAnyDatabase', db: 'admin' },
{ role: 'clusterAdmin', db: 'admin' }
]
});
db = db.getSiblingDB('<my-db>');
db.createUser({
user: '<my-username>',
pwd: '<my-password>',
roles: [
{ role: 'readWrite', db: '<my-db>' },
{ role: 'dbAdmin', db: '<my-db>' }
]
});
config/settings.py ->
import os
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# MongoDB Configuration
MONGO_URI = os.getenv('MONGO_URI', 'mongodb://<my-username>:<my-password>@mongodb:27017/<my-db>?authSource=admin')
DB_NAME = '<my-db>'
config/db.py->
from pymongo import MongoClient
import logging
class Database:
client = None
db = None
@classmethod
def initialize(cls):
"""Initialize database connection with retries"""
cls.client = MongoClient(
MONGO_URI,
maxPoolSize=50,
waitQueueTimeoutMS=2500,
connectTimeoutMS=2500,
serverSelectionTimeoutMS=5000
)
cls.db = cls.client[DB_NAME]
cls._create_indexes()
logging.info("MongoDB connection successful")
@classmethod
def _create_indexes(cls):
"""Create necessary indexes"""
cls.db.tenants.create_index("tenant_name", unique=True)
cls.db.tenant_configs.create_index("cypherDomain", unique=True)
logging.info("MongoDB indexes created successfully")
@classmethod
def get_db(cls):
"""Get database instance with connection check"""
if cls.db is None:
cls.initialize()
return cls.db
db_instance = Database()
当我启动应用程序时,所有服务都会正常启动,没有任何错误。 MongoDB和Flask都显示连接成功,并且我可以在日志中看到MongoDB索引创建成功。但是,当发出注册请求时,它不会反映在数据库中。
日志->
2024-11-13 20:24:07 INFO:root:Application starting up
2024-11-13 20:24:07 INFO:root:MongoDB URI: <my-url>
2024-11-13 20:24:07 INFO:root:Log file location: logs/backend_20241113.log
2024-11-13 20:24:07 INFO:root:Application starting up
2024-11-13 20:24:07 INFO:root:MongoDB URI: <my-url>
2024-11-13 20:24:07 INFO:root:MongoDB connection successful
2024-11-13 20:24:07 INFO:root:Log file location: logs/backend_20241113.log
2024-11-13 20:24:07 INFO:root:MongoDB indexes created successfully
2024-11-13 20:24:07 INFO:root:MongoDB connection successful
2024-11-13 20:24:07 INFO:root:Application starting up
2024-11-13 20:24:07 INFO:root:MongoDB URI: <my-url>
2024-11-13 20:24:07 INFO:root:Log file location: logs/backend_20241113.log
2024-11-13 20:24:07 INFO:root:MongoDB indexes created successfully
2024-11-13 20:24:08 INFO:root:MongoDB connection successful
2024-11-13 20:24:08 INFO:root:MongoDB indexes created successfully
2024-11-13 20:24:08 INFO:root:Application starting up
2024-11-13 20:24:08 INFO:root:MongoDB URI: <my-url>
2024-11-13 20:24:08 INFO:root:Log file location: logs/backend_20241113.log
2024-11-13 20:24:08 INFO:root:MongoDB connection successful
2024-11-13 20:24:08 INFO:root:MongoDB indexes created successfully
2024-11-13 20:25:32 INFO:root:Signup data: {'email': '[email protected]', 'password': 'test123', 'tenant_name': 'db2', 'authProvider': 'email'}
什么会阻止数据插入 MongoDB? 我是 docker 新手,如果出现问题或听起来很愚蠢,抱歉,但我们非常感谢任何帮助:)
我不清楚你的意图。请记住,您创建了两个不同的(!)用户。一位用户的范围为
admin
数据库,另一位用户的范围为 <my-db>
当您连接
mongodb://<my-username>:<my-password>@mongodb:27017/<my-db>?authSource=admin
然后您尝试与用户连接
admin.<my-username>
如果您想与用户连接
<my-db>.<my-username>
,那么您必须使用连接字符串
mongodb://<my-username>:<my-password>@mongodb:27017/<my-db>?authSource=<my-db>
.
我不知道为什么用户可能在
admin
以外的任何地方创建。我建议:
db = db.getSiblingDB('admin');
db.createUser({
user: 'admin-usern',
pwd: 'password',
roles: [
{ role: 'userAdminAnyDatabase', db: 'admin' },
{ role: 'readWriteAnyDatabase', db: 'admin' },
{ role: 'dbAdminAnyDatabase', db: 'admin' }
]
});
db.createUser({
user: 'normal-user',
pwd: 'password',
roles: [
{ role: 'readWrite', db: '<my-db>' },
{ role: 'dbAdmin', db: '<my-db>' }
]
});
然后您就可以随时与
authSource=admin
联系
角色
{ role: 'clusterAdmin', db: 'admin' }
仅与分片集群相关,我认为你没有。
也许,而不是
[
{ role: 'userAdminAnyDatabase', db: 'admin' },
{ role: 'readWriteAnyDatabase', db: 'admin' },
{ role: 'dbAdminAnyDatabase', db: 'admin' }
]
只需授予
{ role: 'root', db: 'admin' }