NestJS на Heroku всегда не может привязать порт - PullRequest
1 голос
/ 13 мая 2019

Я пытаюсь развернуть мой REST API NestJS на Heroku, но всегда получаю следующую ошибку:

 Web process failed to bind to $PORT within 60 seconds of launch

Моя конфигурация довольно проста:

  1. На моем main.ts я запускаю свой сервер с:

    await app.listen(process.env.PORT || AppModule.port);

  2. Я добавил Procfile в корневой каталог моего проекта, который содержит:

    web: npm run start:prod

  3. Мои файлы package.json содержат следующие сценарии:

    "build": "tsc -p tsconfig.build.json", "prestart:prod": "rimraf dist && npm run build", "start:prod": "node dist/main.js",

Процесс на Heroku строится успешно, выводит на экран эти обнадеживающие линии:

TypeOrmModule dependencies initialized
SharedModule dependencies initialized
AppModule dependencies initialized

Но тут же вылетает с:

Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch

Я использую конфигурацию .env в своем приложении, но я удалил все переменные HOST и PORT (и ссылки на код), поэтому я понятия не имею, что может быть причиной этой ошибки. Я что-то упустил?

EDIT Настоящим я делюсь файлами app.module и main.ts:

app.module.ts

@Module({
  imports: [
    SharedModule,
    TypeOrmModule.forRootAsync({
      imports: [SharedModule],
      inject: [ConfigService],
      useFactory: async (configService: ConfigService) => ({
        type: 'postgres',
        host: configService.getString('POSTGRES_HOST'),
        port: configService.getNumber('POSTGRES_DB_PORT'),
        username: configService.getString('POSTGRES_USER'),
        password: configService.getString('POSTGRES_PASSWORD'),
        database: configService.getString('POSTGRES_DB'),
        entities: [__dirname + '/**/*.entity{.ts,.js}'],
      } as PostgresConnectionOptions),
    }),
    UserModule,
  ],
  controllers: [
    AppController,
  ],
  providers: [
    AppService,
  ],
})
export class AppModule {
  static port: number;
  static isDev: boolean;

  constructor(configurationService: ConfigService) {
    console.log(process.env.PORT);
    AppModule.port = configurationService.getNumber('PORT');
    AppModule.isDev = configurationService.getBoolean('ISDEV');
  }
}

My configuration.service.ts - это простая утилита, которая читает файлы .env:

import * as dotenv from 'dotenv';
import * as path from 'path';

@Injectable()
export class ConfigService {
  constructor() {
      const filePath = path.resolve('.env');
      dotenv.config({
      path: filePath,
    });
  }

  getNumber(key: string): number | undefined {
    return +process.env[key] as number | undefined;
  }

  getBoolean(key: string): boolean {
    return process.env[key] === 'true';
  }

  getString(key: string): string | undefined {
    return process.env[key];
  }
}

И, наконец, мой файл main.ts:

async function bootstrap() {
  console.log(process.env.PORT);
  const app = await NestFactory.create(AppModule);
  app.enableCors();
  app.useGlobalPipes(new ValidationPipe(), new TimeStampPipe());
  app.use(json({ limit: '5mb' }));

  app.setGlobalPrefix('api/v1');
  await app.listen(process.env.PORT || AppModule.port);
}
bootstrap();

Может ли быть, что мой configuration.service.ts вмешивается в env-файл heroku?

1 Ответ

1 голос
/ 14 мая 2019

В качестве резюме, будьте осторожны с таймаутом соединения с базой данных, который может привести к глобальному таймауту начальной загрузки heroku, как описано выше

...