You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过Docker Compose部署后NestJS/MongoDB认证失败排查

MongoDB部署后认证失败问题排查

问题背景

本地环境下使用root用户或自建用户连接MongoDB时认证正常,但通过Coolify/Dokploy将服务部署到服务器后,出现认证失败错误,日志提示MongoServerError: Authentication failed.。相关配置信息如下:

Docker Compose 配置

version: '3.8'
services:
  mongodb-dev:
    image: mongo:latest
    container_name: mongodb-dev
    restart: always
    # env_file: ${ENV_FILE:-.env}
    environment:
      MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME}
      MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
      MONGO_INITDB_DATABASE: ${MONGO_INITDB_DATABASE}
    ports:
      - '27017:27017'
    volumes:
      - mongodbdata:/data/db
      - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro # This should be executed by Mongo during startup
    networks:
      - my-network

  my-nest-backend:
    build: .
    container_name: my-nest-backend
    ports:
      - '${PORT}:${PORT}'
    depends_on:
      - mongodb-dev
    networks:
      - my-network
    # env_file: ${ENV_FILE:-.env}
    environment:
      DATABASE_NAME: ${DATABASE_NAME}
      DATABASE_USER: ${DATABASE_USER}
      DATABASE_PASS: ${DATABASE_PASS}
      MONGODB_HOST: ${MONGODB_HOST}
      NODE_ENV: ${NODE_ENV}
      PORT: ${PORT}
      MONGO_URI: mongodb://${DATABASE_USER}:${DATABASE_PASS}@${MONGODB_HOST}:27017/${DATABASE_NAME}?authSource=admin&directConnection=true
    command: npm run start:debug

volumes:
  mongodbdata:

networks:
  my-network:
    driver: bridge

NestJS 配置

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    MongooseModule.forRootAsync({
      useFactory: async () => {
        const logger = new Logger('MongooseModule');
        const uri = process.env.MONGO_URI;

        try {
          // Establish a MongoDB connection with the provided URI
          return {
            uri,
            useNewUrlParser: true,
            useUnifiedTopology: true
          };
        } catch (error) {
          logger.error(`MyLog Failed to connect to MongoDB: ${error.message}`, error.stack);
          throw error; // Rethrow to prevent app from starting with bad DB connection
        }
      },
    }),
    QuoteModule,
    PhilosopherModule,
    AuthModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule implements OnModuleInit {
  private readonly logger = new Logger(AppModule.name);

  async onModuleInit() {
    this.logger.log('MyLog AppModule initialized');
  }
}

错误日志

MongoServerError: Authentication failed.
        at Connection.sendCommand (/app/node_modules/mongoose/node_modules/mongodb/lib/cmap/connection.js:297:27)
        at processTicksAndRejections (node:internal/process/task_queues:96:5)
        at async Connection.command (/app/node_modules/mongoose/node_modules/mongodb/lib/cmap/connection.js:325:26)
        at async executeScram (/app/node_modules/mongoose/node_modules/mongodb/lib/cmap/auth/scram.js:79:22)
        at async ScramSHA1.auth (/app/node_modules/mongoose/node_modules/mongodb/lib/cmap/auth/scram.js:39:16)
        at async performInitialHandshake (/app/node_modules/mongoose/node_modules/mongodb/lib/cmap/connect.js:101:13)
        at async connect (/app/node_modules/mongoose/node_modules/mongodb/lib/cmap/connect.js:19:9)

可能的原因及解决方法

1. 环境变量未正确注入

  • 部署平台可能未正确加载.env文件中的变量,导致DATABASE_USER、DATABASE_PASS等参数为空或错误,生成的连接字符串无效。
  • 排查:进入后端容器执行printenv查看环境变量值,或在NestJS的useFactory中打印uri确认连接字符串是否正确。
  • 解决:确保部署平台已配置所有所需环境变量,或启用Docker Compose中的env_file字段加载本地.env文件(注意部署时同步该文件到服务器)。

2. MongoDB初始化脚本未执行

  • 挂载的mongo-init.js可能因路径错误、权限问题,或数据卷已有旧数据(mongodbdata卷)导致脚本未执行,自定义用户未创建。
  • 排查:查看MongoDB容器日志,搜索docker-entrypoint-initdb.d相关内容确认脚本执行情况;进入MongoDB容器,用root用户登录后查看用户列表:
    mongo -u ${MONGO_INITDB_ROOT_USERNAME} -p ${MONGO_INITDB_ROOT_PASSWORD} --authenticationDatabase admin
    use admin
    show users
    use ${DATABASE_NAME}
    show users
    
  • 解决:
    • 确保mongo-init.js路径正确,且部署时已同步到服务器对应目录;
    • 若数据卷存在旧数据,删除mongodbdata卷后重启容器(注意备份数据);
    • 检查脚本语法,确保创建用户时指定了正确的roles和authenticationDatabase。

3. 连接字符串authSource配置错误

  • 连接字符串指定authSource=admin,但如果自定义用户是创建在目标数据库而非admin库,会导致认证失败。
  • 排查:确认用户创建时的authenticationDatabase参数,对应调整连接字符串的authSource。
  • 解决:若用户在目标库创建,将authSource改为目标库名称;若在admin库创建,确保用户拥有目标库的访问权限。

4. 网络解析异常(伪装成认证失败)

  • 后端容器无法解析${MONGODB_HOST}(如容器名在部署平台网络中无法识别),导致连接请求未正确到达MongoDB,返回类似认证失败的错误。
  • 排查:在后端容器中ping${MONGODB_HOST},或用mongosh "${MONGO_URI}"手动测试连接。
  • 解决:确保MONGODB_HOST设置为MongoDB容器的服务名(mongodb-dev),且两个容器在同一网络(my-network)中;若部署平台有特殊网络规则,调整网络配置确保容器间通信正常。

5. 密码特殊字符未编码

  • 密码包含@、:、/等特殊字符时,未进行URL编码会导致连接字符串解析错误,最终认证失败。
  • 排查:打印生成的MONGO_URI,检查密码部分是否正确编码(如@需替换为%40)。
  • 解决:在环境变量中对密码进行URL编码,或在NestJS中用encodeURIComponent()处理后拼接连接字符串:
    const encodedPass = encodeURIComponent(process.env.DATABASE_PASS);
    const uri = `mongodb://${process.env.DATABASE_USER}:${encodedPass}@${process.env.MONGODB_HOST}:27017/${process.env.DATABASE_NAME}?authSource=admin&directConnection=true`;
    

内容的提问来源于stack exchange,提问作者V.Sch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 09:37:04