Deploying a NestJS App With Heroku
Deploying a NestJS application with Heroku is an easy possibility to host your application. This tutorial is a step-by-step guide for deploying small (side) projects by using GitHub and the Heroku web app (without the CLI). I deployed my Animal Crossing GraphQL application this way.
Prerequisites
I assume that you already have:
- npm installed
- Node.js installed (version greater than 8)
- a locally working NestJS application with a package.json
- a Heroku account
- a GitHub account
1. Add/Modify your .gitignore
If you don’t already have a .gitignore file, create one in the root folder of your project and add the following lines:
/node_modules
/dist
npm-debug.log
.DS_Store
/*.env
This ensures that you don’t commit these files to Git, preventing build artifacts from getting into your GitHub repository.
2. Specify your Node.js version
Heroku needs to know the version of your Node.js runtime, to be able to run it on Heroku. You can check for your node version by running this command in your terminal:
node --version
Now add this to your package.json
(if you are running e.g. on version 14.16.1
):
"engines": {
"node": "14.16.1"
},
3. Specify start script and add Procfile
If you already started your app you should be familiar with the npm run start
script. If you used the NestJS CLI command nest new <project-name>
for creating your project you should have the following start scripts in your package.json
:
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
When running your app a dist
folder with a main.js
file is created, which is used for the deployment. You can leave this like this, as this already works perfectly for simple projects.
“Heroku apps include a Procfile that specifies the commands that are executed by the app on startup.” (from https://devcenter.heroku.com/articles/procfile)
Create a file named Procfile
without a file extension and place it in the root directory. As we want to run the start script, we write it in this file like this:
web: npm run start:prod
4. Set the correct port
The web server on your local machine can listen to any open, unreserved port. Heroku needs to listen to a specific port that is set in the PORT
environment variable. To make the server listen on a specific port (e.g. 8080
), when the variable is not set you should adapt your main.ts
as follows:
await app.listen(process.env.PORT || 8080);
5. Create Heroku app
Create a new app in your Heroku dashboard at https://dashboard.heroku.com/. After choosing the name and region choose “Connect to GitHub” as a deployment method in the “Deploy” tab and choose the repository you want to deploy. When choosing the automatic deployment, the app automatically gets deployed when your master branch changes. After this, you should see your deployed application 🎉
6. (Optional) Enable GraphQL playground in production
If you use GraphQL in your application and you want to reveal your docs and schema of the app you can enable the playground in production. Please do not do this, if it is not necessary! Revealing this information is a security vulnerability, as it reveals your schema and the introspection query. As I created an API for animal crossing I wanted to share the docs in the playground and needed to enable it. This can be done by explicitly setting introspection
and playground
in app.modules.ts
:
@Module({
imports: [
GraphQLModule.forRoot({
introspection: true,
playground: true
}),
],
})