Prepare a Node.js Application for Production on Ubuntu 20.10

Updated on November 21, 2023
Prepare a Node.js Application for Production on Ubuntu 20.10 header image

Overview

Delivering a secure, fast, and robust Node.js application is vital for a good user experience. This tutorial explains how to prepare your Node.js application for production.

Prerequisites

1. Set up a Server Firewall

A firewall ensures only specific ports on a server can receive and send data. Enabling only the ports required reduces the chance of exploiting the server.

  1. Install ufw.

     $ sudo apt-get install ufw
  2. Enable the HTTP port.

     $ sudo ufw allow 80
  3. Enable the HTTPS port.

     $ sudo ufw allow 443
  4. Enable the SSH port if you intend on using it. Otherwise, skip this step. (It is recommended that you set the SSH port to another port for added security. Click Here to learn how to do this. Make sure to replace 22 with your chosen port.)

     $ sudo ufw allow 22
  5. Start UFW service.

     $ sudo ufw enable
  6. Confirm service is running without errors.

     $ sudo ufw status

    It should report:

     Status: active

2. Preparing Node.js Application

Preparing a Node.js application for production will help mitigate errors and create a reliable deployment process.

  1. Install a middleware package for server security headers. This middleware will help secure headers sent from the server in every request. Research which package works best with your framework. However, for an Express.js server, install Helmet.js.

     $ npm i --save helmet
  2. Add the middleware to your server code:

     const express = require("express");
     const helmet = require("helmet");
    
     const app = express();
    
     app.use(helmet());
  3. Change server listening port to 8080 for reverse proxying through Nginx. Although the server firewall prohibits clients from connecting to any other port except for ports 80 (HTTP) and 443 (HTTPS), setting up a reverse proxy will allow the Node.js application to communicate through port 443 (HTTPS) automatically.

     const express = require("express");
    
     app.listen(8080);
  4. Install PM2 to manage the Node.js application to run in the background as a process. PM2 will automatically restart the application server if it crashes, manage application logs, and monitor performance.

     $ sudo npm install pm2 -g
  5. Start the Node.js application. Make sure to replace server_file.js with the name of your main server file.

     $ pm2 start server_file.js

    Confirm it logs PM2 Successfully daemonized.

  6. Set PM2 to run on startup.

     $ pm2 startup

3. Set up Nginx

Nginx is a robust web server used in production for its speed and painless Implementation. It allows Node.js applications to scale easily as it centrally manages all HTTP requests while integrating SSL, caching, reverse-proxying, and much more. This allows developers to write Node.js code without worrying about communicating through HTTPS as Nginx handles it when serving data to the client.

  1. Install nginx.

     $ sudo apt-get install nginx
  2. Verify the server is running.

     $ sudo systemctl status nginx

    It should report:

     Active: active (running)
  3. Change to the Nginx server configuration directory.

     $ cd /etc/nginx/sites-enabled/
  4. Edit the default file and replace the content inside with the following. Make sure to change example.com to your domain and provide a valid path for ssl_certificate and ssl_certificate_key.

     # redirect HTTP traffic to HTTPS
     server {
             listen 80;
             server_name example.com www.example.com;
             return 301 https://example.com$request_uri;
     }
    
     # HTTPS server
     server {
             listen 443 ssl;
             server_name example.com;
    
             access_log /var/log/nginx/example.com.log;
    
             ssl_certificate /path/to/certificate/example.com.crt;
             ssl_certificate_key /path/to/key/example.com.key;
    
             location / {
                 proxy_set_header HOST $host;
                     proxy_set_header X-Real-IP $remote_addr;
                     proxy_pass http://127.0.0.1:8080; # Node.js Application
             }
     }
  5. Copy the default file to /etc/nginx/sites-available/.

     $ cp default /etc/nginx/sites-available/
  6. Restart Nginx.

     $ sudo systemctl restart nginx
  7. Verify reverse proxy works by navigating to your domain name in a web browser.

     https://example.com

Conclusion

You have successfully prepared and secured your Node.js application.