Modern web applications rely on a firm and secure backend. Thus, it is essential to create backend applications that are scalable, secure, and architecturally sophisticated to be managed by small and/or large teams of developers.
Modern developers prefer to use JavaScript on both the front and back end. Express.js is an excellent JavaScript backend framework used by most developers. However, its minimal architecture makes it unsuitable for scalability and maintainability by large teams. This is where Nest.js comes into play. Nest.js has a built-in architecture, which makes it highly suitable for scalability and deployment. Also, its native support for TypeScript makes it more productive for developers than vanilla JavaScript.
In this tutorial, you will learn how to deploy a NestJS application using the Nginx web server, on a VPS. You will learn how you can put your application on the web with the required security.
Before proceeding with the tutorial, you must meet the following requirements:
In this section, you will install the NestJS CLI and create a basic NestJS app, which you will learn to deploy using Nginx in later sections.
To install the NestJS CLI in your Ubuntu machine, open a terminal and type in the following command.
npm i -g @nestjs/cli
This will install the NestJS command line interface on your machine. Next, you will learn to create a new NestJS project.
Now, NestJS provides two ways to start a new project. You can choose the method that best suits you.
Type in the following command to create a NestJS project with the CLI.
nest new <project-name>
Output? Which package manager would you ❤️ to use? (Use arrow keys)
❯ npm
yarn
pnpm
You would get an output like following after completion.
OutputCREATE node_app/.eslintrc.js (663 bytes)
CREATE node_app/.prettierrc (51 bytes)
CREATE node_app/README.md (3340 bytes)
CREATE node_app/nest-cli.json (171 bytes)
CREATE node_app/package.json (1947 bytes)
CREATE node_app/tsconfig.build.json (97 bytes)
CREATE node_app/tsconfig.json (546 bytes)
CREATE node_app/src/app.controller.ts (274 bytes)
CREATE node_app/src/app.module.ts (249 bytes)
CREATE node_app/src/app.service.ts (142 bytes)
CREATE node_app/src/main.ts (208 bytes)
CREATE node_app/src/app.controller.spec.ts (617 bytes)
CREATE node_app/test/jest-e2e.json (183 bytes)
CREATE node_app/test/app.e2e-spec.ts (630 bytes)
This will create a new project in the present working directory. You can provide the absolute path for a different directory as well, instead of the <project-name>
.
NestJS provides an alternate way to start a new project. It is a git repository that serves as the boilerplate template. You can clone that repository and start the project with the following commands.
git clone https://github.com/nestjs/typescript-starter.git <project-directory >
Once the cloning is complete, you need to cd
to the project directory and then run npm install
to install the dependencies from package.json
cd <project-directory>
npm install
Once the project is ready, you can start the application server using the following command:
npm run start
This will run the application on http://localhost:3000. Now, you have a basic NestJS application ready to run on localhost.
Once you have developed your application, you can run tests on it to check whether the application is running as expected or not. NestJS provides default Jest tests, which run tests on your application. You can start the test using the following command:
npm run test
This will test your application and return results similar to the following :
Output> node_app@0.0.1 test
> jest
PASS src/app.controller.spec.ts
AppController
root
✓ should return "Hello World!" (24 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.895 s
Ran all test suites.
In the following section, you will learn how to deploy this NestJS application on your web server using Nginx as a reverse proxy.
Now, we can move forward with setting up the webserver to host this NestJS application. We will be using the reverse proxy approach. In this approach, we will run our application on the localhost on a certain port and then, use the Nginx server to proxy any requests to the VPS public IP address or domain to the application on localhost. Using reverse proxy servers is an industry practice as it enhances the security of the web server by creating a barrier between incoming requests and the backend application itself. Also, reverse proxies allow for better load management on the server, especially when using the server to host multiple web applications.
We will start by installing the pm2
package manager, which will manage the application in runtime.
You can install the pm2
process manager using the following command.
npm install -g pm2
This will install the pm2 globally on your machine.
Now, configure Nginx to run the application. Make sure that you have allowed the Nginx app in your firewall for both HTTP and HTTPS, as mentioned in the prerequisite tutorial. If you are using the ufw
firewall, you can do it by following the commands.
ufw enable
ufw allow ‘Nginx Full‘
Now, you will create a configuration block for our NestJS app. It is recommended to create new configuration blocks for new applications, instead of editing the default configuration. To create the block, type the following code in your terminal.
sudo nano /etc/nginx/sites-available/your_domain
Here, we have used your_domain for the application, but you will change this to the name of your application. Then, in the editor, type in the following code:
server {
server_name your_domain www.your_domain;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Now, you will create a symlink, which tells Nginx to look for available web applications in the sites-available folder:
sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/
Also, you would need to disable the default symlink otherwise, nginx will redirect all requests to the default site. Use the following command to unlink it.
sudo unlink /etc/nginx/sites-enabled/default
Now, restart the Nginx service using the following command.
sudo systemctl restart nginx
Now, you will set up the pm2 package manager to handle the execution of your NestJS application. Change the working directory to your Nestjs application directory and type the following command.
pm2 start npm --name "your_domain" –- start
You can run the following command to configure pm2 on server restarts.
pm2 startup
Once you are done with setting up the application on pm2, go ahead and save the pm2 process list with the following:
pm2 save
Now, we have set up the web application to run on startup and configured Nginx to reverse proxy to our application running on localhost.
You can test the web application from your console by typing the following command.
curl http://localhost
Since we have set up the reverse proxy on the server IP address itself, any request to the public IP address to your server, domain, or request on localhost from the server will redirect to the NestsJS application your_domain
.
OutputHello World!
In the next section, you will learn to add SSL to your application, which will allow you to use HTTPS protocol for your requests.
So far, you have learned how to deploy a fully working NestJS application with the Nginx server. However, this deployment is using the HTTP protocol which is not recommended in production due to its exploitation vulnerability. Therefore, you would like to move to the HTTPS protocol, which is the encrypted version of HTTP. HTTPS uses SSL/TLS certificates provided by a Certificate Authority. These certificates are specific to a website and encrypt the communication between client and server.
In this section, you will learn to add the Let’s Encrypt SSL/TLS certificate for your site.
Note:: To proceed with this section, you need to have an A certificate for your domain. In this example, we have used your_domain, but you should add SSL certificates only after adding your domain to the website.
Let’s Encrypt provides a CLI to manage and automate SSL certificates for consumers. You can install the tool with the following command:
sudo apt install certbot python3-certbot-nginx
This installs the certbot client on your Ubuntu VPS.
Now, you can fetch the SSL certificates for your domain using the following command
sudo certbot --nginx -d <your_domain> -d <www.your_domain>
You will need to replace your_domain
with the actual name of your domain. If this is the first time you are running certbot on your VPS, you will asked to enter your email and agree to user terms. Provide the necessary information and proceed.
Note: This will only work if you have a legitimate domain and you have associated your domain with your NestJS application.
Once the certificates are installed, you will be able to redirect all requests to HTTPS. It is recommended that you redirect all requests to ensure the integrity of your website.
Info: The certificates installed by certbot have a validity period of 90 days. However, certbot automates the renewal of these certificates on its own, so you need not check for their validity frequently.
In this tutorial, you learned how to deploy a NestJS application in production on an Ubuntu VPS using the Nginx web server. You also learned how to set up a NestJS project and a reverse proxy for your application using Nginx. Lastly, you learned how to add SSL/TLS certificates for your server’s domain, ensuring the integrity of communications between your clients and server.
You can expand this knowledge by creating complex NestJS applications, including but not limited to database integration, input validators, etc.
The author selected OWASP Foundation to receive a donation as part of the Write for DOnations program.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
There are some errors: Before giving access to nginx via ufw ensure that nginx is installed:
When provisioning pm2 there’s a second dash missed: