Dockerized Flask 应用程序无法在 MongoDB 中保留数据 – 日志中没有错误,但数据库中没有数据

问题描述 投票:0回答:1

我正在开发一个在连接到 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 新手,如果出现问题或听起来很愚蠢,抱歉,但我们非常感谢任何帮助:)

mongodb docker flask deployment
1个回答
0
投票

我不清楚你的意图。请记住,您创建了两个不同的(!)用户。一位用户的范围为

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' }
© www.soinside.com 2019 - 2024. All rights reserved.