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

Docker部署Node.js后端遇TypeORM 'driver not connected'错误求助

Docker中运行后端应用遇到'driver not connected'错误排查

问题描述

在Docker中运行后端应用时,发起请求时遇到了driver not connected错误,不确定问题是否出在数据库连接方式上,服务层使用了事务和Repository。

数据库连接相关代码

class DataSourceFactory {
  private Isource: DataSource;

  get source(): DataSource {
    return this.Isource;
  }

  constructor() {
    this.Isource = new DataSource({
      type: 'postgres',
      host: process.env.DB_HOST,
      port: parseInt(process.env.DB_PORT as string),
      username: process.env.DB_USER,
      password: process.env.DB_PASS,
      database: process.env.DB_NAME,
      synchronize: process.env.NODE_ENV === EnvResult.dev ? true : false,
      entities: ['src/entities/**/*{entity.ts,entity.js}'],
      logging: process.env.NODE_ENV === EnvResult.dev ? true : false,
      subscribers: [EveryEventSubscriber],
      namingStrategy: new SnakeNamingStrategy(),
    });
  }
}
export default new DataSourceFactory();
import DataSourceFactory from '@source/data.source';
import { logger } from '@/logger/custom.logger';
class DatabaseProvider {
  async init(): Promise<void> {
    try {
      await DataSourceFactory.source.initialize();
      logger.client.info('Database connection is successful::...');
    } catch (err: any) {
      logger.client.error(err.message);
    }
  }
}

export const databaseSource = new DatabaseProvider();

服务层事务示例

@Service()
export class MemberService {
  private readonly dbSource = DataSourceFactory.source;

  public async register(
    dto: MemberRegisterDto
  ): Promise<CreatedResponse<IdentifierResDto>> {
    return await this.dbSource.manager.transaction(
      async (transactionalEntityManager: EntityManager) => {
        try {
          const newMember = await transactionalEntityManager
            .withRepository(MemberRepository)
            .customCreate(dto);

          const newUser = await transactionalEntityManager
            .withRepository(UserRepository)
            .customCreate(dto, newMember);

          const newToken = await transactionalEntityManager
            .withRepository(TokenRepository)
            .customCreate({
              operation: TokenOperationType.verifyAfterRegistration,
              userId: newUser.id,
              memberId: newMember.id,
              publicId: newUser.publicId,
              app: newUser.app,
              globalDeviceName: newUser.globalDeviceName,
            });

          new ElectronicMessaging({
            contact:
              newUser.app.type === ApplicationType.Src
                ? newUser.I.phone
                : newUser.I.mail,
            content: {
              token: newToken.clientToken,
              fullName: newUser.name + ' ' + newUser.surname,
            },
            operation:
              newToken.operation as TokenOperationType.verifyAfterRegistration,
          }).load(newToken.app.type);

          const convertData = TransformService.convert<
            IdentifierResDto,
            UserEntity
          >(newUser, IdentifierResDto, 'excludeAll');

          return new CreatedResponse<IdentifierResDto>(
            Code.SUCCESS_CREATE,
            Messages.SUCCESS_CREATE,
            convertData
          );
        } catch (error) {
          throw error;
        }
      }
    );
  }}

Docker Compose配置示例

version: '3.9'
services:
  postgresql:
    image: postgres
    restart: unless-stopped
    ports:
      - '5732:5732'

    networks:
      - app

    environment:
      POSTGRES_PASSWORD: mypassword
      POSTGRES_USER: postgres

  nats:
    image: nats-streaming:0.17.0
    networks:
      - app
    command:
      - '-p'
      - '4222'
      - '-m'
      - '8222'
      - '-hbi'
      - '5s'
      - '-hbt'
      - '5s'
      - '-hbf'
      - '2'
      - '-SD'
      - '-cid'
      - 'bestneting'
      - '-cluster'
      - 'nats://0.0.0.0:6222'
    ports:
      - 4222:4222
      - 8222:8222

  backend:
    image: nurettinsenbackend/bestnetbackend
    restart: on-failure

    depends_on:
      - postgresql
      - nats
    command: sh -c "while ! nc -z postgresql 5432; do sleep 1; done && npm run dev"
    environment:
      - DB_PASS=mypassword
      - DB_HOST=postgresql
      - NATS_URL=http://nats:4222

    ports:
      - 2000:2000
    networks:
      - app

  mail:
    image: nurettinsenbackend/mail
    restart: on-failure
    depends_on:
      - nats
    environment:
      - NATS_URL=http://nats:4222
    ports:
      - 4000:4000
    networks:
      - app

  sms:
    image: nurettinsenbackend/bestnetsms
    restart: on-failure
    depends_on:
      - nats
    environment:
      - NATS_URL=http://nats:4222
    ports:
      - 6000:6000
    networks:
      - app

networks:
  app:
    driver: bridge

核心排查与修复点

  • 端口不匹配问题:
    Docker Compose中postgres容器映射的是5732:5732,但后端启动命令里用nc -z postgresql 5432检测的是默认5432端口,同时数据源配置里的DB_PORT未在backend环境变量中设置。要么把postgres容器的内部端口改回默认5432(映射外部5732,即ports: - '5732:5432'),要么在backend的environment中添加DB_PORT=5732,并把启动命令里的检测端口改成5732。
  • 缺失环境变量:
    backend服务的environment中缺少DB_USER和DB_NAME,虽然postgres默认用户是postgres,默认数据库名也是postgres,但显式配置更稳妥,添加- DB_USER=postgres和- DB_NAME=postgres到backend的环境变量中。
  • 数据源初始化时机:
    确保databaseSource.init()在应用启动时被调用,且必须等待初始化完成后再启动HTTP服务或处理请求。比如在main函数中先执行await databaseSource.init(),再启动服务。
  • 事务调用时机:
    确认在调用dbSource.manager.transaction之前,数据源已经完成初始化。如果应用还没建立数据库连接就触发请求,必然会出现driver not connected错误。

内容的提问来源于stack exchange,提问作者Kerem Esen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 22:00:53