How to Deploy a Node.js App to Production

Deploy a Node.js

Developers often use their local system (Windows or Linux) to install and create a Node.js application. However, when it comes to moving a Node.js application in the production environment then it will be very difficult for any developer who doesn’t know about hosting.

In order to host a Node.js application in the production, you will need to perform several things including, Purchase a VPS hosting, Domain name, Bind a domain name to VPS, Install and Create Node.js to VPS, Create a service to manage the Node.js application, Configure Nginx to host a Node.js application, Install SSL on your Domain, etc. In this post, I will try my best to explain step by step procedure to host a Node.js application in the production environment.

You will learn the following:

Prerequisites

  • A server running Ubuntu 20.04.
  • A valid domain name pointed with your server
  • A root password is configured on your server.

If you want to host Node.js application on Cloud or VPS and don’t know how to choose the best Cloud and VPS hosting provider. You can read my guide on 13 Best “Cheap VPS Hosting” and “Cloud Hosting” Providers – 2021.

Step 1 – Install Node.js

Before installing Node.js, you will need to install the required dependencies to your system. Run the following command to install all dependencies:

apt-get install curl gnupg2 build-essential wget -y

Next, add the Node Source repository with the following command:

curl -sL https://deb.nodesource.com/setup_14.x | bash -

Once the repository is added, install the Node.js by running the following command:

apt-get install node.js -y

After installing Node.js, verify the Node.js version with the following command:

node -v

You should see the Node.js version in the following output:

v14.16.0

Step 2 – Create a Node.js Application

In this section, we will create a simple Node.js application named myapp.js. Create a new myapp.js file inside /opt directory:

nano /opt/myapp.js

Add the following code:

const http = require('http');
const hostname = 'localhost';
const port = 3000;

const server = http.createServer((req, res) => {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.end('This is My First Node.js Application!\n');
});

server.listen(port, hostname, () => {
    console.log(`Server running at http://${hostname}:${port}/`);
});

Save and close the file once you are finished. Next, run the application with the following command:

cd /opt
node myapp.js

If all is well, you should get the following output:

Server running at http://localhost:3000/

Now, press CTRL+C to stop the application. We will configure a systemd service file to manage the Node.js application.

Step 3 – Create a Service File for Node.js Application

It is recommended to create a systemd service file to manage and control the Node.js application. This way, you don’t need to start your application every time after the system reboot. Create a systemd service file for Node.js application with the following command:

nano /lib/systemd/system/nodeapp.service

Add the following content:

[Unit]
Description=Node.js Application
After=syslog.target network.target

[Service]
Type=simple
User=root
WorkingDirectory=/opt/
Environment=NODE_ENV=production
ExecStart=/usr/bin/node myapp.js

Restart=always

[Install]
WantedBy=multi-user.target

Save and close the file then reload the systemd daemon with the following command:

systemctl daemon-reload

Next, start the Node.js service and enable it to start at system reboot:

systemctl start nodeapp
systemctl enable nodeapp

To verify the Node.js service, run the following command:

systemctl status nodeapp

Output:

● nodeapp.service - Node.js Application
     Loaded: loaded (/lib/systemd/system/nodeapp.service; disabled; vendor preset: enabled)
     Active: active (running) since Fri 2021-03-26 13:45:53 UTC; 6s ago
   Main PID: 9973 (node)
      Tasks: 11 (limit: 2353)
     Memory: 7.7M
     CGroup: /system.slice/nodeapp.service
             └─9973 /usr/bin/node myapp.js

Mar 26 13:45:53 ubuntu2004 systemd[1]: Started Node.js Application.
Mar 26 13:45:53 ubuntu2004 node[9973]: Server running at http://localhost:3000/

Step 4 – Configure Nginx to Host Node.js Application

In this section, we will install Nginx and configure it as a reverse proxy to access the Node.js application on port 80. First, install the Nginx package using the following command:

apt-get install nginx -y

After installing Nginx, create an Nginx configuration file for the Node.js application:

nano /etc/nginx/conf.d/nodeapp.conf

Add the following content:

upstream nodebackend {
   server localhost:3000;
   keepalive 32;
}

server {
   listen 80;
   server_name nodeapp.linuxbuz.com;

   location / {
       client_max_body_size 50M;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_http_version 1.1;
       proxy_pass http://nodebackend;
   }
}

Save and close the file then verify the Nginx for any syntax error: Note: Replace nodeapp.linuxbuz.com with your own domain name.

nginx -t

Output:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Finally, restart the Nginx service to apply the changes:

systemctl restart nginx

Step 5 – Secure Node.js Application with Let’s Encrypt Free SSL

It is also a good idea to secure your Node.js website with Let’s Encrypt Free SSL. You will need to install the Certbot client package to install and manage the Let’s Encrypt SSL. Run the following command to install the Certbot package:

apt-get install python3-certbot-nginx -y

After installing the Certbot client, run the following command to download Let’s Encrypt SSL and configure Nginx to use the downloaded SSL.

certbot --nginx -d nodeapp.linuxbuz.com

You will be asked to provide your valid email address and accept the term of service as shown below:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): [email protected]

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for nodeapp.linuxbuz.com
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/conf.d/nodeapp.conf

Next, you will need to choose whether or not to redirect HTTP traffic to HTTPS:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2

Type 2 and hit Enter to start the installation. Once the installation has been completed, you should see the following output:

Redirecting all traffic on port 80 to ssl in /etc/nginx/conf.d/nodeapp.conf

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://nodeapp.linuxbuz.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=nodeapp.linuxbuz.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/nodeapp.linuxbuz.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/nodeapp.linuxbuz.com/privkey.pem
   Your cert will expire on 2020-10-30. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

 - We were unable to subscribe you the EFF mailing list because your
   e-mail address appears to be invalid. You can try again later by
   visiting https://act.eff.org.

Step 6 – Verify Node.js Application

Now, your Node.js application is hosted with an Nginx web server and secured with Let’s Encrypt SSL. You can access it using the URL https://nodeapp.linuxbuz.com. You should see your Node.js application page in the following screen:

node.js dashboard

About Hitesh Jethva

I am Hitesh Jethva Founder and Author at LinuxBuz.com. I felt in love with Linux when i was started to learn Linux. I am a fan of open source technology and have more than 15+ years of experience in Linux and Open Source technologies.

View all posts by Hitesh Jethva