Prepare a Node.js Application for Production on Ubuntu 20.10
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
- Add a non-root sudo user.
- Follow the best practices to update Ubuntu.
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.
Install
ufw
.$ sudo apt-get install ufw
Enable the HTTP port.
$ sudo ufw allow 80
Enable the HTTPS port.
$ sudo ufw allow 443
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
Start UFW service.
$ sudo ufw enable
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.
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
Add the middleware to your server code:
const express = require("express"); const helmet = require("helmet"); const app = express(); app.use(helmet());
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);
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
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
.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.
Install
nginx
.$ sudo apt-get install nginx
Verify the server is running.
$ sudo systemctl status nginx
It should report:
Active: active (running)
Change to the Nginx server configuration directory.
$ cd /etc/nginx/sites-enabled/
Edit the
default
file and replace the content inside with the following. Make sure to changeexample.com
to your domain and provide a valid path forssl_certificate
andssl_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 } }
Copy the
default
file to/etc/nginx/sites-available/
.$ cp default /etc/nginx/sites-available/
Restart Nginx.
$ sudo systemctl restart nginx
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.