10

I'm currently trying to deploy the basic starter template generated by the Nest.JS CLI (as of version 5.3.0) and seem to be getting a timeout on app startup. I'm wondering if anyone has managed to deploy to Heroku?

I'm not sure whether or not I need to include some kind of Procfile?

Also, there doesn't seem to be much info around deploying the Nest.JS

The Heroku logs when I try to deploy.

heroku[web.1]: Starting process with command `npm start`
app[web.1]: 
app[web.1]: > testy@0.0.0 start /app
app[web.1]: > ts-node -r tsconfig-paths/register src/main.ts
app[web.1]: 
app[web.1]: [Nest] 21   - 2018-10-16 06:52:17   [NestFactory] Starting Nest application...
app[web.1]: [Nest] 21   - 2018-10-16 06:52:17   [InstanceLoader] AppModule dependencies initialized +21ms
app[web.1]: [Nest] 21   - 2018-10-16 06:52:17   [RoutesResolver] AppController {/}: +48ms
app[web.1]: [Nest] 21   - 2018-10-16 06:52:17   [RouterExplorer] Mapped {/, GET} route +7ms
app[web.1]: [Nest] 21   - 2018-10-16 06:52:17   [NestApplication] Nest application successfully started +3ms
app[web.1]: Error waiting for process to terminate: No child processes
heroku[web.1]: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
heroku[web.1]: Stopping process with SIGKILL
heroku[web.1]: Process exited with status 22
heroku[web.1]: State changed from starting to crashed
heroku[web.1]: State changed from crashed to starting

my package.json file is below...

{
  "name": "testy",
  "version": "0.0.0",
  "description": "description",
  "author": "",
  "license": "MIT",
  "scripts": {
    "format": "prettier --write \"src/**/*.ts\"",
    "start": "ts-node -r tsconfig-paths/register src/main.ts",
    "start:dev": "nodemon",
    "start:debug": "nodemon --config nodemon-debug.json",
    "prestart:prod": "rimraf dist && tsc",
    "start:prod": "node dist/main.js",
    "start:hmr": "node dist/server",
    "lint": "tslint -p tsconfig.json -c tslint.json",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:e2e": "jest --config ./test/jest-e2e.json",
    "webpack": "webpack --config webpack.config.js"
  },
  "dependencies": {
    "@nestjs/common": "^5.1.0",
    "@nestjs/core": "^5.1.0",
    "reflect-metadata": "^0.1.12",
    "rxjs": "^6.2.2",
    "typescript": "^3.0.1"
  },
  "devDependencies": {
    "@nestjs/testing": "^5.1.0",
    "@types/express": "^4.16.0",
    "@types/jest": "^23.3.1",
    "@types/node": "^10.7.1",
    "@types/supertest": "^2.0.5",
    "jest": "^23.5.0",
    "nodemon": "^1.18.3",
    "prettier": "^1.14.2",
    "rimraf": "^2.6.2",
    "supertest": "^3.1.0",
    "ts-jest": "^23.1.3",
    "ts-loader": "^4.4.2",
    "ts-node": "^7.0.1",
    "tsconfig-paths": "^3.5.0",
    "tslint": "5.11.0",
    "webpack": "^4.16.5",
    "webpack-cli": "^3.1.0",
    "webpack-node-externals": "^1.7.2"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".spec.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  }
}

If anyone has any experience in deploying this stack it'd be great to hear from you

BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
Kyle Bennett
  • 121
  • 1
  • 1
  • 5

5 Answers5

8

Heroku assigns you a port by default and adds the port to the environment variables (env), so you can set the port to a fixed number, you need to change your main file to:

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

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT || 3000);
}
bootstrap();
Juan Velasquez
  • 385
  • 4
  • 15
  • 1
    You can mark your own answer as accepted, so that other people know that this problem was solved. :-) – Kim Kern Feb 01 '19 at 22:20
6

After some hours... it's up and running!

1. package.json (pay attention on: scripts, @nestjs version, engines)

{
  "name": "nest",
  "version": "0.0.0",
  "description": "description",
  "author": "",
  "license": "MIT",
  "scripts": {
    "build": "tsc -p tsconfig.build.json",
    "format": "prettier --write \"src/**/*.ts\"",
    "start": "ts-node -r tsconfig-paths/register src/main.ts",
    "start:dev": "nodemon",
    "start:debug": "nodemon --config nodemon-debug.json",
    "start:prod": "node dist/main.js",
    "prestart:prod": "rimraf dist && npm run build",
    "postinstall": "npm run prestart:prod",
    "lint": "tslint -p tsconfig.json -c tslint.json",
    "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",
    "test:e2e": "jest --config ./test/jest-e2e.json",
    "heroku-postbuild": "npm install --only=dev --no-shrinkwrap && npm run build"
  },
  "dependencies": {
    "@nestjs/common": "6.7.2",
    "@nestjs/core": "6.7.2",
    "@nestjs/jwt": "0.2.0",
    "@nestjs/mongoose": "5.2.2",
    "@nestjs/passport": "5.1.0",
    "@nestjs/platform-express": "6.7.2",
    "bcrypt": "3.0.2",
    "mongoose": "5.3.15",
    "passport": "0.4.0",
    "passport-jwt": "4.0.0",
    "reflect-metadata": "0.1.12",
    "rimraf": "2.6.2",
    "rxjs": "6.2.2",
    "typescript": "3.0.1"
  },
  "devDependencies": {
    "@nestjs/testing": "5.1.0",
    "@types/express": "4.16.0",
    "@types/jest": "23.3.1",
    "@types/node": "10.7.1",
    "@types/supertest": "2.0.5",
    "jest": "23.5.0",
    "nodemon": "1.18.3",
    "prettier": "1.14.2",
    "supertest": "3.1.0",
    "ts-jest": "23.1.3",
    "ts-loader": "4.4.2",
    "ts-node": "7.0.1",
    "tsconfig-paths": "3.5.0",
    "tslint": "5.11.0"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".spec.ts$",
    "transform": {
      ".+\\.(t|j)s$": "ts-jest"
    },
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  },
  "engines": {
    "node": "8.9.4"
  }
}

2. Procfile (location - same as package.json) Yes it's file without type. Can be created with Notepad.

web: npm run start:prod

3. Enable installing devDependencies (if needed)

heroku config:set NPM_CONFIG_PRODUCTION=false
Marian Turchyn
  • 519
  • 5
  • 6
5

I made the following changes to deploy a newly generated nest.js app:

  1. main.ts - changed

await app.listen(3000);

to

await app.listen(process.env.PORT || 3000);

  1. added Procfile contents: web: npm run start:prod

  2. package.json - added heroku-postbuild script so my scripts look like:

  "scripts": {
    "build": "tsc -p tsconfig.build.json",
    "format": "prettier --write \"src/**/*.ts\"",
    "start": "ts-node -r tsconfig-paths/register src/main.ts",
    "start:dev": "nodemon",
    "start:debug": "nodemon --config nodemon-debug.json",
    "prestart:prod": "rimraf dist && npm run build",
    "start:prod": "node dist/main.js",
    "lint": "tslint -p tsconfig.json -c tslint.json",
    "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",
    "test:e2e": "jest --config ./test/jest-e2e.json",
    "heroku-postbuild": "npm install --only=dev --no-shrinkwrap && npm run build"
  },

Currently running at: https://server-ts.herokuapp.com

Matloob
  • 115
  • 1
  • 2
  • 7
5

Seems that all solutions here was for previous versions of Nest.

In my case (NestJS v7.5.1) start command looks like "nest start"

And all worked after adding "@nestjs/cli" to dependencies.

PokatilovArt
  • 1,111
  • 11
  • 13
  • This works for me as well. I don't know exactly what I'm talking about, but it looks like it ends up rebuilding the whole app when running nest start, as opposed to serving the dist folder. But it works... – wongz Apr 11 '22 at 00:38
3

If you're using the free tier in Heroku, then you can only use npm start, while yours is start:prod. Try replacing "start:prod": "node dist/main.js" with "start": "node dist/main.js".

batbrain9392
  • 565
  • 6
  • 15
  • Thanks alot it really worked.!!!! just added followng lines in script in package.json. "heroku-postbuild": "npm install --only=dev --no-shrinkwrap && npm run build" "start": "node dist/main", – Umer Ali Jul 25 '20 at 08:58