Docker Compose部署NestJS+MongoDB遇ECONNREFUSED错误求助
解决Docker Compose中NestJS + TypeORM连接MongoDB的ECONNREFUSED错误
问题现象
在Windows 11主机上使用Docker Compose搭建NestJS + TypeORM + MongoDB环境时,出现数据库连接被拒绝的错误,错误日志如下:
nestjs-docker-api-1 | [Nest] 1 - 07/23/2022, 8:45:32 AM ERROR [TypeOrmModule] Unable to connect to the database. Retrying (1)... nestjs-docker-api-1 | MongoServerSelectionError: connect ECONNREFUSED 127.0.0.1:27018 nestjs-docker-api-1 | at Timeout._onTimeout (/usr/src/app/node_modules/mongodb/lib/sdam/topology.js:293:38) nestjs-docker-api-1 | at listOnTimeout (internal/timers.js:554:17) nestjs-docker-api-1 | at processTimers (internal/timers.js:497:7)
现有配置
Dockerfile
FROM node:12 # Create app directory WORKDIR /usr/src/app # A wildcard is used to ensure both package.json AND package-lock.json are copied COPY package*.json ./ # Install app dependencies RUN npm install # Bundle app source COPY . . EXPOSE 8080 # Creates a "dist" folder with the production build RUN npm run build # Start the server using the production build CMD [ "node", "dist/main.js" ]
docker-compose.yml
version: "3.9" services: mongo: image: mongo ports: - "27018:27017" restart: always environment: ME_CONFIG_MONGODB_ADMINUSERNAME: root ME_CONFIG_MONGODB_ADMINPASSWORD: example api: image: image_name build: . depends_on: - mongo environment: NODE_ENV: development PORT: 3000 USERNAME : root, PASSWORD : example ports: - "8000:3000"
TypeORM配置
@Module({ imports: [ TypeOrmModule.forRoot({ type: 'mongodb', host: 'localhost', port: 27018, database: 'admin', entities: [], synchronize: true, })], controllers: [AppController], providers: [AppService], }) export class AppModule {}
解决方案
1. 修正MongoDB连接地址与端口
Docker容器内的localhost指向容器自身,而非主机。Docker Compose中,服务名可作为域名直接访问,因此:
- 将TypeORM配置中的
host改为mongo(对应docker-compose中的服务名) - 端口改为Mongo容器内部的
27017(主机映射的27018仅用于主机访问容器,容器间通信使用内部端口)
2. 补充MongoDB认证配置
docker-compose中设置了管理员账号,但TypeORM配置未包含认证信息,需添加:
username和password(建议通过环境变量获取,避免硬编码)- 指定
authSource: 'admin'(root用户属于admin数据库)
3. 修复MongoDB初始化环境变量
ME_CONFIG_*是mongo-express的配置变量,MongoDB官方镜像初始化root用户需使用MONGO_INITDB_ROOT_USERNAME和MONGO_INITDB_ROOT_PASSWORD,否则不会创建指定的管理员账号。
4. 解决容器启动顺序问题
depends_on仅保证容器启动顺序,不保证服务就绪。通过healthcheck配合depends_on的condition,确保NestJS容器在Mongo服务可用后再启动。
5. 修正docker-compose环境变量语法
api服务的USERNAME和PASSWORD后多了逗号,需删除,否则环境变量会包含无效字符。
修改后的配置
修改后的TypeORM配置
@Module({ imports: [ TypeOrmModule.forRoot({ type: 'mongodb', host: 'mongo', port: 27017, database: 'admin', username: process.env.USERNAME, password: process.env.PASSWORD, authSource: 'admin', entities: [], synchronize: true, })], controllers: [AppController], providers: [AppService], }) export class AppModule {}
修改后的docker-compose.yml
version: "3.9" services: mongo: image: mongo ports: - "27018:27017" restart: always environment: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: example healthcheck: test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"] interval: 5s timeout: 5s retries: 5 api: image: image_name build: . depends_on: mongo: condition: service_healthy environment: NODE_ENV: development PORT: 3000 USERNAME: root PASSWORD: example ports: - "8000:3000"
内容的提问来源于stack exchange,提问作者Thịnh Cường
相关产品推荐
相关产品推荐

