Nestjs框架: 微服务容器化部署与网络通信解决方案

容器化部署架构

1 ) 关键配置文件

  • Dockerfile:定义镜像构建流程(生产依赖安装 → 应用构建 → 最终镜像生成)

  • .dockerignore:排除非必要文件,缩小镜像体积

  • 核心优化:

    dockerfile 复制代码
    # 使用轻量级基础镜像 (Alpine)  
    FROM node:18-alpine AS production  
    WORKDIR /app  
    COPY package*.json ./  
    RUN npm ci --only=production  # 仅安装生产依赖  
    
    # 构建阶段  
    FROM node:18-alpine AS build  
    WORKDIR /app  
    COPY . .  
    RUN npm run build  # 执行项目构建  
    
    # 最终镜像  
    FROM production  
    COPY --from=build /app/dist ./dist  # 仅复制构建产物  
    EXPOSE 3000  
    CMD ["node", "dist/main"]  

    优势:

    • 最终镜像不含构建缓存,体积减少约60%
    • 阶段隔离保障生产环境纯净性

2 ) Docker Compose编排

yaml 复制代码
version: '3.8'
services:
  main:  # 主服务
    build: 
      context: ./app/main  # Dockerfile路径 
    restart: always 
    env_file: ./.env  # 加载环境变量
    ports:
      - "3000:3000"  # 端口映射

  client:  # 客户端服务 
    build: 
      context: ./app/client
    restart: always
    env_file: ./.env
    ports:
      - "3001:3001"
    depends_on:
      - main

启动命令:

bash 复制代码
docker-compose up --build -d  # 强制重建镜像并后台运行

依赖管理与构建问题解决

1 ) Monorepo依赖冲突

  • 问题根源:子项目存在独立 package-lock.json 导致依赖不一致

  • 修复方案:

    bash 复制代码
    # 删除所有子项目锁文件
    rm -f ./app/main/package-lock.json ./app/client/package-lock.json
    
    # 在根目录统一安装依赖
    npm install 
  • 调整 Dockerfile

    dockerfile 复制代码
    # 删除以下冗余指令
    COPY package-lock.json ./  # 移除锁文件拷贝

2 ) 环境变量动态注入

  • .env 文件配置:

    env 复制代码
    NODE_ENV=production 
    SERVICE_HOST=main  # 容器内通信使用服务名
  • 客户端动态主机配置:

    typescript 复制代码
    // app.module.ts (client)
    @Module({
      imports: [
        ClientsModule.register([{
          name: 'MAIN_SERVICE',
          transport: Transport.TCP,
          options: {
            host: process.env.SERVICE_HOST || 'localhost', // 动态解析主机 
            port: 3000
          }
        }])
      ]
    })
    export class AppModule {}

网络通信与安全实践

1 ) 容器间通信机制

  • 无需暴露端口:同一Compose网络内通过服务名称直接访问

    typescript 复制代码
    // Client 调用 Main 服务
    this.client.send({ cmd: 'REQUEST' }, 'MAIN_SERVICE'); 
  • 网络隔离拓扑:
    外部请求 Client:3001 内部网络 Main:3000

2 ) 跨域安全强化

  • 生产环境加密方案:

    yaml 复制代码
    # docker-compose.yml 扩展 
    services:
      main:
        networks:
          micro-net:
            aliases:
              - main.internal  # 内部域名
  • TLS加密通信(可选):

    typescript 复制代码
    // 启用加密传输
    transport: Transport.TCP,
    options: {
      tls: { 
        cert: readFileSync('cert.pem'),
        key: readFileSync('key.pem')
      }
    }

3 ) NestJS 微服务客户端代码示例:

typescript 复制代码
// client/src/app.module.ts 
import { ClientsModule, Transport } from '@nestjs/microservices';

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MAIN_SERVICE',
        transport: Transport.TCP,
        options: {
          host: process.env.NODE_ENV === 'production' ? 'main' : 'localhost',
          port: 3000,
        },
      },
    ]),
  ],
})
export class AppModule {}
typescript 复制代码
// client/src/app.controller.ts 
import { Controller, Get, Inject } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';

@Controller()
export class AppController {
  constructor(@Inject('MAIN_SERVICE') private readonly client: ClientProxy) {}

  @Get()
  async getData() {
    return this.client.send({ cmd: 'fetchData' }, {}).toPromise();
  }
}
  • 网络安全实践:

    • 仅暴露网关端口(如 client3001),内部服务(如 main)不直接映射到宿主机。
    • 跨集群通信需使用 TLS 加密(需运维工具辅助,避免手动配置证书)。
  • 端到端测试:

    • 启动服务:docker-compose up -d
    • 验证通信:访问 client 端口(http://localhost:3001)应返回 main 服务的响应。
    • 关键结论:同一 Docker Compose 网络中的服务可通过服务名互访,实现安全隔离。

部署验证流程

1 ) 启动与监控

bash 复制代码
docker-compose up -d --build  # 构建并启动 
docker ps  # 验证容器状态

2 ) 服务测试

测试目标 访问方式 预期响应
Client服务 http://localhost:3001 调用Main服务返回数据
Main服务 内部端口main:3000 不直接暴露,仅限内部访问

3 ) 问题排查路径

bash 复制代码
# 查看容器日志 
docker logs -f workspace-client-1 

# 进入容器诊断 
docker exec -it workspace-main-1 sh
curl http://localhost:3000/health  # 服务健康检查

核心总结

1 ) 容器化最佳实践

  • 多阶段构建:分离开发/生产依赖,镜像体积缩减至200MB以下
  • 依赖治理:Monorepo项目需统一锁文件管理
  • 动态配置:通过 .env 实现环境无感切换

2 ) 微服务通信铁律

  • 内部服务互访:通过 Docker Compose 服务名称直接通信
  • 外部暴露控制:仅网关类服务开放端口,内部服务隔离运行
  • 安全基线:生产环境强制启用 TLS 或服务网格加密

3 ) 运维提效

  • docker-compose.yml 统一管理服务生命周期
  • 容器日志集中采集(ELK/Sentry)
  • 异地部署时采用 Kubernetes 管理容器集群
相关推荐
❀͜͡傀儡师2 小时前
docker安装mac系统
macos·docker·容器
0***145 小时前
PHP在微服务中的架构设计
微服务·云原生·架构
uzong6 小时前
Mermaid: AI 时代画图的魔法工具
后端·架构
TH_16 小时前
腾讯云-(8)-宝塔面板-安装Docker
docker·云计算·腾讯云
RUNNING123!7 小时前
RedHat 7.9 docker 安装 zabbix
docker·容器·zabbix
爱吃牛肉的大老虎7 小时前
网络传输架构之gRPC讲解
网络·架构
香吧香7 小时前
docker网络总结
docker
故渊ZY7 小时前
Java 代理模式:从原理到实战的全方位解析
java·开发语言·架构
weixin_449290018 小时前
docker_ollama
docker·容器·eureka
起个名字逛街玩8 小时前
前端正在走向“工程系统化”:从页面开发到复杂产品架构的深度进化
前端·架构