Deploy a NestJS and Angular NX Monorepo to Digital Ocean’s App Platform

Taylor Ackley
3 min readJul 23, 2021

This article will cover how to deploy an NX MonoRepo that uses NestJS for the backend and Angular for the front end. As a bonus, we’ll walk through setting up MongoDB as well. The good news is this is very quick and easy, from beginning to end this is about a 10 to 15 minute process.

For the purposes of the app we will be deploying, we will use a single Digital Ocean component to serve both the API and the static assets.

First, let’s get some assumptions out of the way. In order for you to follow this article, the following items should be true.

  • You have already signed up for Digital Ocean and have an account in good standing.
  • Your code is in a hosted Git Repository.
  • You have already created the app on Digital Ocean and connected it to your Git repository.
  • You have a mostly working API and front-end.

And now for the fun part!

Step 1 — Setup NestJS to Serve Static Assets

We will rely on NestJS to serve up the static front-end assets since we’re only using a single Digital Ocean component. Out of the box, NestJS is not set up to serve static assets. Luckily, it is pretty easy to set up.

First, install the NestJS Static Module.

npm install --save @nestjs/serve-static

Next, add the module to the NestJS imports. For most users, this will be the file <repo root>/apps/api/src/app/app.module.ts

import { Module } from '@nestjs/common';import { ConfigModule, ConfigService } from '@nestjs/config';import { ServeStaticModule } from '@nestjs/serve-static';import { join } from 'path';
@Module({imports: [ ConfigModule.forRoot(), ServeStaticModule.forRoot({ rootPath: join(__dirname, '..', 'name-of-your-app'), exclude: [], })],controllers: [],providers: [],})export class AppModule {}

Be sure to replace the directory name (‘name-of-your-app’). If you need to check, run the build command for the front-end (ng build ) and check the name of the folder in <repo-root>/dist/apps/ . For example, if you’re app is called activity-feed then you would replace rootPath: join(__dirname, '..', 'name-of-your-app’) it with rootPath: join(__dirname, '..', 'activity-feed’)

Next time you run the API, it will also serve up the last build of your front-end Angular app. You should be able to see it if you point your browser to http://localhost:3333.

Step 2 — Add NPM Scripts

In your package.json, presumably located at the top level of your repo, add two new scripts.

"scripts": {
// clipped for brevity
"build-ci": "ng build --prod && ng build api",
"start-app": "node dist/apps/api/main.js",
},

To recap, we’re adding two simple npm scripts.

build-ci will build both the the front-end and API, one after the other. Obviously, feel free to swap out the prod configuration for the one you need.

The end result of the build-ci script is we will have a dist directory at the top-level of the repo containing both of our built apps.

start-app will do exactly what it says, start the compiled NestJS backend in a node process.

Step 3 — Fill Out the Digital Ocean App Spec

If you have already created your app in Digital Ocean, you probably saw a dialog asking you about your build and run commands. If you filled out the default information, that's okay.

Head over to your app, and go to the settings section. Look for the “App Spec” section. Select the option to download the app spec.

Open up the downloaded app spec file in YAML format in your favorite text editor, but not vim, because you don’t have anything to prove.

Replace npm build with npm build-ci on the build_command line.
Replace npm start with npm start-app on the run_command line.

Pay attention to your copy & paste job. It’s YAML so extra spaces and line breaks can break your app spec.

Save your updated app spec and head back to your app in the browser. Click the blue Upload button located underneath where you downloaded the app spec. The page should update with your new app sec. Make sure you see our npm scripts!

Step 4 — Conclusion

If you need to, add any environment variables in the settings section. After that, your app should deploy without issue.

--

--