Deploy an Angular + NestJS app to Heroku

Florian BESSET
CodeShake
Published in
6 min readMay 19, 2020

You made a great app based on Angular and NestJS but now you wonder how to host it without getting a headache and above all: for free. Then Heroku might be a right choice ! Let’s see how to make all these folks work together.

Main idea

What we want to achieve here is to “package” our front-end and our back-end apps as one in order to deploy it to a single Heroku app. Yes we can !

So we’re going to build our Angular app for production and put the build result (I mean files) into our NestJS app at a specific location. Then, we will tell NestJS to serve those files as soon as the requested URL doesn’t match any API route. And of course, NestJS must be still able to serve API responses after that.

What you need to know before we start

If you ended up here, I assume you already know Angular, NestJS and Heroku. I won’t tell you how to create a project with those frameworks, how they work or other basic stuff like that.

I will just show you what is inside my basic Angular and NestJS apps and how to deploy them as a single one to Heroku with few tips.

Our demonstration app is going to be a basic user list. It will be splitted in two parts: user-list-front and user-list-back, each one in a separate folder.

Angular App

Ok so first things first, I’m gonna show you what’s inside my Angular app.

AppComponent

Our main component will only contain our basic app layout, title and a mandatory <router-outlet> .

HomeComponent

Its only purpose is to show a clickable button leading to another page. This won’t be very useful, I agree, but it’s just to show you that routing will be working well on our front app once deployed on Heroku.

DisplayUserListComponent

This component will call UserService to fetch users list and display it.

UserService

Will fetch users from back-end.

AppRoutingModule

Two routes will be registered: one “by default” to display HomeComponent and another one to load DisplayUserListComponent .

Environment

A little something you have to change before going any further is the environment files. We’re actually going to declare the URL of our back-end inside those files because it won’t be the same wether we are in development mode or in production mode.

NestJS App

Now that we have a very basic but still working Angular app, let’s work on the back side of the Force.

UserController

A simple controller with one endpoint allowing us to get all users. I suggest you to prefix all your controller routes with /api like I did here, so you make sure all your endpoints serving datas are located behind the same path.

UserService

To keep things simple, our app won’t be linked to any database but of course, you’ll want to fetch data dynamically from a source in a “real” app.

Main.ts file

Last but not least, you have to modify the main.ts file for two things:

  1. To make your app start on a dynamic port (Heroku won’t let you choose the port on which your app will be reacheable, so it stores it inside process.env.PORT )
  2. To activate CORS (otherwise your front-end won’t reach your back-end)

At this point, you should have a working app, with a front-end fetching and displaying datas provided by the back-end, which is nice ! But now let’s dive into the serious business !

Building Angular App and put it into NestJS

As said earlier, NestJS will be the place where all the magic will occur. So there will go our built Angular application.

We have two choices here:

  1. Launch the build command on our Angular app manually, wait for it to finish and then move Angular’s dist folder into NestJS by drag and drop or cut/paste
  2. Or create a script inside NestJS package.json and make it work for us

Feel free to choose the option you prefer, anyway I’m gonna show you how to implement the second one :)

Angular’s package.json script

Our script will:

  • Remove previous folder that might already exist from a previous build
  • Build our Angular app
  • Move the Angular build result (files and folders) into a “front” folder in NestJS app

As this script will call native functions on the OS you are using in order to move files or delete a repository, I give you a Windows version and a Mac OS one. Both of them are supposed to go to the “script” section of your Angular’s package.json file.

Windows:

"build:win": "(if exist ..\\user-list-back\\front rmdir ..\\user-list-back\\front /s /q) && ng build --prod && move dist/user-list-front ..\\user-list-back\\front"

MacOS:

"build:mac": "rm -rf ../user-list-back/front && mkdir ../user-list-back/front && ng build --prod && mv dist/user-list-front/* ../user-list-back/front/"

Ask NestJS to serve static files

At this point, a new folder called “front” should be present inside your NestJS app. It contains our built Angular app. Now we want to tell NestJS to serve those Angular files.

First, install the ServeStatic NestJS module:

npm install --save @nestjs/serve-static

Then import and configure the ServeStaticModule inside your AppModule like so:

Important notice: from now, absolutely none of your controllers should respond and serve data to the root route http://localhost:3000 .

Why ? Because static files have to be served at this specific URL. If one of your controller responds to that route, files will never be served. This acts like a fallback: if no route matches, then serve static files.

So what now ? Try to navigate in your web browser to http://localhost:3000 and you will be amazed to see that we’ve got our front-end showing and our datas from back-end displayed as well !

Heroku deployment

Now you saw that our app is working well behind http://localhost:3000. It’s time to put everything on Heroku and make it available to the world !

Create Heroku app

First, install the Heroku CLI to make things easier:
https://devcenter.heroku.com/articles/heroku-cli

Then, create a new app on your Heroku account and name it the way you want. Mine will be called “angular-nestjs-demo”.

Config vars

Heroku needs a tiny bit of configuration before it can deploy our app.

Go to your Heroku app, then Settings and find the “Config Vars” section and click on “Reveal Vars” button.

Here you have to enter this key-value:

NPM_CONFIG_PRODUCTION false

This will skip pruning our dev dependencies, which are needed to run the app correctly once deployed.

Push your project on Heroku

Once created, you can go to your back-end project and run this command to link your repository to Heroku:

heroku git:remote -a <your-heroku-app-name>

Now create your first commit. It should include all your project, obviously. Then you will be able to push your commit directly to Heroku and it will take care of the deployment for you. Just run:

git push heroku master

Once pushing and deploy is done, go to your Heroku app by URL, in my case it will be https://angular-nestjs-demo.herokuapp.com

And voilà ! Here’s what you should see:

And if you navigate to /users by clicking on the button:

As you can see, Angular routing is working fine, as well as the API call because the user list is nicely displayed.

Here you go, you know how to deploy Angular & NestJS project to Heroku :)

GitHub project

You can find this project at this location:

https://github.com/Flobesst/angular-nestjs-heroku-demo

--

--