Search code examples
dockernestjsmicroservicesamazon-ecsaws-copilot

Nest Js Microservices deployment on ECS with aws Copilot


Hey everyone i am trying to deploy to production a basic nestjs microservice stack : One application is a basic nestjs application that will be used as Api Gateway and will communicate to services with TCP transport The second application is a nestjs microservice

//Gateway/src/main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(8000);
}
bootstrap();
 

And the service

//Restaurant/src/main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Transport, TcpOptions } from '@nestjs/microservices';
async function bootstrap() {
  const app = await NestFactory.createMicroservice(AppModule, {
    transport: Transport.TCP,
    options: {
      host: '0.0.0.0',
      port: 8001,
    },
  } as TcpOptions);
  await app.listen();
}
bootstrap();

Then in my Gateway i am registering the microservice in the module like this

// Gateway/src/app.module.ts

@Module({
  imports: [
    ConfigModule.forRoot({
      envFilePath: [`.env.stage.${process.env.STAGE}`],
    }),
  ],
  controllers: [RestaurantController, AppController],
  providers: [
    ConfigService,
    {
      provide: 'RESTAURANT_SERVICE',
      useFactory: (configService: ConfigService) => {
        return ClientProxyFactory.create({
          options: {
            host: '0.0.0.0',
            port: 8001,
          },
        });
      },
      inject: [ConfigService],
    },
  ],
})
export class AppModule {}

When i am starting each application in my local machine all workings perfect. Now i used aws copilot to deploy my api-gw and my service into same copilot app For the api-gw i choosed Load Balanced Web Service For the service i choosed Backend Service

api-gw manifest file

name: api-gw
type: Load Balanced Web Service


    http:
      path: '/'
    
    image:
      build: Dockerfile
      port: 8000
    
    cpu: 256       # Number of CPU units for the task.
    memory: 512    # Amount of memory in MiB used by the task.
    platform: linux/x86_64  # See https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/#platform
    count: 1       # Number of tasks that should be running in your service.
    exec: true     # Enable running commands in your container.
    network:
      connect: true # Enable Service Connect for intra-environment traffic between services.

restaurant service manifest file

name: restaurant
type: Backend Service

image:
  build: Dockerfile
  port: 8001

cpu: 256       # Number of CPU units for the task.
memory: 512    # Amount of memory in MiB used by the task.
platform: linux/x86_64     # See https://aws.github.io/copilot-cli/docs/manifest/backend-service/#platform
count: 1       # Number of tasks that should be running in your service.
exec: true     # Enable running commands in your container.
network:
  connect: true # Enable Service Connect for intra-environment traffic between services.

The deployment of both of the services is working fine , but when i am sending request to the api-gw , the api-gw trying to connect to the restaurant service and i am getting error

Error: connect ECONNREFUSED 0.0.0.0:8001

Like you see i enable the network true property on both of the services in the manifest files

Thank for your help


Solution

  • The network field enables AWS Service Connect.

    To use TCP, please use a NLB (the default for Load-Balanced Web Services is an ALB). See this Copilot docs page for instructions on specifying a NLB.