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';