Deploy an Angular + NestJS app to Heroku

Flobesst
Flobesst
May 19 · 6 min read

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.

Image for post
Image for post

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.

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

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.

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

Will fetch users from back-end.

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

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.

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.

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.

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 :)

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/"

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 !

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”.

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

Image for post
Image for post

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

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:

Image for post
Image for post

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

Image for post
Image for post

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

CodeShake

Learnings and insights from SFEIR community.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store