如何在NestJS中于不同Docker容器运行独立微服务
实现独立容器部署NestJS主HTTP服务与微服务
要把主HTTP服务和微服务拆分到独立Docker容器,核心是将单进程多服务的代码拆成独立的Nest应用实例,再通过Docker和docker-compose分别编排部署。以下是具体步骤:
1. 拆分独立的服务入口文件
将原来的单进程代码拆为三个独立入口,每个对应一个服务:
主HTTP服务入口(src/main-http.ts)
作为对外提供HTTP接口的主服务,内部通过微服务客户端调用其他服务:
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); // 可按需配置CORS、全局管道等HTTP服务设置 await app.listen(3000); } bootstrap();
TCP微服务入口(src/main-tcp.ts)
单独启动TCP协议的微服务:
import { NestFactory } from '@nestjs/core'; import { Transport, MicroserviceOptions } from '@nestjs/microservices'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, { transport: Transport.TCP, options: { port: 3001, }, }); await app.listen(); } bootstrap();
Redis微服务入口(src/main-redis.ts)
单独启动Redis协议的微服务:
import { NestFactory } from '@nestjs/core'; import { Transport, MicroserviceOptions } from '@nestjs/microservices'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, { transport: Transport.REDIS, options: { host: 'redis', // 用docker-compose中的Redis服务名,而非localhost port: 6379, }, }); await app.listen(); } bootstrap();
2. 配置服务启动脚本
在package.json中添加三个启动脚本,方便本地测试和Docker构建:
{ "scripts": { "start:http": "nest start --watch --entryFile main-http", "start:tcp": "nest start --watch --entryFile main-tcp", "start:redis": "nest start --watch --entryFile main-redis", "build:http": "nest build --entryFile main-http", "build:tcp": "nest build --entryFile main-tcp", "build:redis": "nest build --entryFile main-redis" } }
3. 编写通用Dockerfile
在项目根目录创建通用Dockerfile(也可按需为每个服务单独编写):
FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build EXPOSE 3000 3001 CMD ["npm", "run", "start:http"]
4. 编写docker-compose.yml
创建docker-compose.yml,定义所有服务和依赖:
version: '3.8' services: # 主HTTP服务 http-server: build: . command: npm run start:http ports: - "3000:3000" networks: - microservice-network depends_on: - tcp-microservice - redis-microservice - redis # TCP微服务 tcp-microservice: build: . command: npm run start:tcp ports: - "3001:3001" networks: - microservice-network # Redis微服务 redis-microservice: build: . command: npm run start:redis networks: - microservice-network depends_on: - redis # Redis数据库 redis: image: redis:alpine ports: - "6379:6379" networks: - microservice-network volumes: - redis-data:/data # 自定义网络,服务间通过服务名通信 networks: microservice-network: driver: bridge # 持久化Redis数据 volumes: redis-data:
5. 调整微服务客户端配置
在主HTTP服务的app.module.ts中,用docker-compose的服务名替换localhost:
import { Module } from '@nestjs/common'; import { ClientsModule, Transport } from '@nestjs/microservices'; import { AppController } from './app.controller'; import { AppService } from './app.service'; @Module({ imports: [ ClientsModule.register([ { name: 'TCP_MICROSERVICE', transport: Transport.TCP, options: { host: 'tcp-microservice', // 对应docker-compose中的服务名 port: 3001, }, }, { name: 'REDIS_MICROSERVICE', transport: Transport.REDIS, options: { host: 'redis', // 对应docker-compose中的Redis服务名 port: 6379, }, }, ]), ], controllers: [AppController], providers: [AppService], }) export class AppModule {}
6. 启动所有服务
在项目根目录执行命令,构建并启动容器:
docker-compose up --build
此时主HTTP服务、TCP微服务、Redis微服务会分别运行在独立容器中,通过自定义网络实现跨容器通信。
内容的提问来源于stack exchange,提问作者repo
相关产品推荐
相关产品推荐

