NestJS deployment

So basicly i’m trying to deploy a nestjs app and even if tweek the vercel.json file so that the deployment at least succeeds, when i try to access a swagger or any other route it gives me a 404 error. (Obs: AT DEV ENV EVERYTHING WORKS FINE)

vercel.json:

{
  "version": 2,
  "buildCommand": "npm run build",
  "devCommand": "npm run start:dev",
  "installCommand": "npm install --legacy-peer-deps",
  "outputDirectory": "dist"
}

package.json

{
  "name": "commerce-blog.api",
  "version": "0.0.1",
  "description": "",
  "author": "Gustavo Augusto",
  "private": true,
  "license": "UNLICENSED",
  "scripts": {
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "node dist/main.js",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug --watch",
    "start:prod": "node dist/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "typeorm": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js",
    "typeorm:migration:generate": "npm run typeorm -- migration:generate -n",
    "migration:run": "npm run typeorm -- -d src/lib/database/database.providers.ts migration:run",
    "seed:run": "ts-node -r tsconfig-paths/register ./node_modules/typeorm-extension/bin/cli.cjs seed:run  -d src/lib/database/database.providers.ts",
    "seed:create": "ts-node ./node_modules/typeorm-extension/bin/cli.cjs seed:create"
  },
  "dependencies": {
    "@nestjs/bull": "^10.2.2",
    "@nestjs/common": "^10.4.6",
    "@nestjs/config": "^3.3.0",
    "@nestjs/core": "^10.4.6",
    "@nestjs/jwt": "^10.2.0",
    "@nestjs/passport": "^10.0.3",
    "@nestjs/platform-express": "^10.4.6",
    "@nestjs/platform-socket.io": "^10.4.6",
    "@nestjs/schedule": "^4.1.1",
    "@nestjs/swagger": "^8.0.1",
    "@nestjs/terminus": "^10.2.3",
    "@nestjs/typeorm": "^10.0.2",
    "@nestjs/websockets": "^10.4.6",
    "@socket.io/redis-adapter": "^8.3.0",
    "bcrypt": "^5.1.1",
    "bull": "^4.16.3",
    "cron": "^3.1.8",
    "dotenv": "^16.4.5",
    "nestjs-typeorm-paginate": "^4.0.4",
    "nestjs-zod": "^4.1.0",
    "passport": "^0.7.0",
    "passport-jwt": "^4.0.1",
    "passport-local": "^1.0.0",
    "pg": "^8.13.1",
    "redis": "^4.7.0",
    "reflect-metadata": "^0.2.2",
    "rxjs": "^7.8.1",
    "socket.io": "^4.8.1",
    "typeorm": "^0.3.20",
    "typeorm-extension": "^3.6.2",
    "zod": "^3.23.8"
  },
  "devDependencies": {
    "@jest/types": "^29.6.3",
    "@nestjs/cli": "^10.4.5",
    "@nestjs/schematics": "^10.2.3",
    "@nestjs/testing": "^10.4.6",
    "@types/bcrypt": "^5.0.2",
    "@types/express": "^5.0.0",
    "@types/jest": "^29.5.14",
    "@types/node": "^22.8.4",
    "@types/passport-jwt": "^4.0.1",
    "@types/supertest": "^6.0.2",
    "@typescript-eslint/eslint-plugin": "^8.12.2",
    "@typescript-eslint/parser": "^8.12.2",
    "eslint": "^9.13.0",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-prettier": "^5.2.1",
    "jest": "^29.7.0",
    "prettier": "^3.3.3",
    "source-map-support": "^0.5.21",
    "supertest": "^7.0.0",
    "ts-jest": "^29.2.5",
    "ts-loader": "^9.5.1",
    "ts-node": "^10.9.2",
    "tsconfig-paths": "^4.2.0",
    "typescript": "^5.6.3"
  }
}

main.ts

import { Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';

import { AppModule } from './app.module';
import { corsConfig } from './config/cors.config';
import { ENV_VARIABLES, IS_DEV_ENV } from './config/env.config';
import { DataBaseInterceptor } from './lib/http-exceptions/errors/interceptors/database.interceptor';
import { NotFoundInterceptor } from './lib/http-exceptions/errors/interceptors/not-found.interceptor';
import { BadRequestInterceptor } from './lib/http-exceptions/errors/interceptors/bad-request.interceptor';
import { UnauthorizedInterceptor } from './lib/http-exceptions/errors/interceptors/unauthorized.interceptor';
import { DataSourceInterceptor } from './lib/http-exceptions/errors/interceptors/conction-data-source.interceptor';

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

  try {
    app.enableCors({
      origin: corsConfig.allowedDomains,
    });
    app.enableShutdownHooks();
    app.setGlobalPrefix('server');

    /**
     * -----------------------------------------------------------------------------
     * HTTP Interceptor
     * -----------------------------------------------------------------------------
     */
    app.useGlobalInterceptors(
      new UnauthorizedInterceptor(),
      new DataSourceInterceptor(),
      new BadRequestInterceptor(),
      new NotFoundInterceptor(),
      new DataBaseInterceptor(),
    );

    if (IS_DEV_ENV) {
      const [{ SwaggerModule }, { swaggerConfig }, { writeFileSync }] =
        await Promise.all([
          import('@nestjs/swagger'),
          import('./config/swagger.config'),
          import('fs'),
        ]);

      const document = SwaggerModule.createDocument(app, swaggerConfig);

      writeFileSync('swagger-document.json', JSON.stringify(document, null, 2));

      SwaggerModule.setup('server', app, document);
    }

    await app.listen(ENV_VARIABLES.PORT);
  } catch (err) {
    Logger.debug(JSON.stringify({ err }, null, 2));
    process.exit(1);
  }
}
bootstrap();

env.config.ts:

import 'dotenv/config';
import { z } from 'zod';

import {
  stringSchema,
  optionalStringSchema,
  optionalUrlStringSchema,
  optionalStringToIntegerSchema,
} from 'src/shared/schemas.shared';

export const envSchema = z.object({
  DATABASE_ROOT_PASSWORD: stringSchema,
  DATABASE_DATABASE_NAME: stringSchema,
  DB_PORT: optionalStringToIntegerSchema.default('5432'),
  DATABASE_HOST: optionalStringSchema.default('localhost'),
  // REDIS_HOST: optionalStringSchema.default('localhost'),
  // REDIS_PASSWORD: stringSchema,
  // REDIS_PORT: stringToIntegerSchema,
  DB_USER: stringSchema,
  JWT_SECRET: stringSchema,
  JWT_REFRESH_SECRET: stringSchema,
  JWT_REFRESH_EXPIRES_IN: stringSchema,
  JWT_ISSUER: optionalUrlStringSchema,
  JWT_AUDIENCE: optionalUrlStringSchema,
  JWT_EXPIRES_IN: stringSchema,
  PORT: optionalStringToIntegerSchema.default('5000'),
  ENV: z.enum(['prod', 'dev']).default('dev'),
});

export type EnvType = z.infer<typeof envSchema>;

export const ENV_VARIABLES = envSchema.parse(process.env);

export const IS_DEV_ENV = ENV_VARIABLES.ENV === 'dev';

Hi, @marcellosamura-gmail!

We have this community thread about how to debug these types of errors. Might be helpful!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.