Deploy node.js app in production.

Building a RESTful API using Express and Node.js is fun until it’s ready to serve in a production environment. There are many real-world challenges to properly deploying an API or your application backend. However, in most cases, we want to make our API scalable while keeping in mind that it should be lightweight on the server. In my personal experience, there are multiple ways to make it happen. Although PM2 is a good approach, there’s a more efficient way to deploy the application in production.

I’m assuming that you have the source code of your Node.js application and that you know the basics of the command line interface. So let’s get our hands dirty.

Install Node.js on your server.

Installing Node.js can be tricky depending on your web server’s operating system. I’m using Ubuntu 22.04, so here is the process for installing it:

curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - &&\
sudo apt-get install -y nodejs

This will add the official Node Source Binary distribution repository to your package manager’s source list and install Node.js 18 on your server. 

Install the latest Nginx mainline distribution.

Nginx mainline is shipped with brotli compression module, and it’s much more stable than the stable distribution (I don’t know why 🤷‍♂️). You can install it by adding the Nginx mainline PPA:

sudo add-apt-repository ppa:ondrej/nginx-mainline && sudo apt update
sudo apt install nginx

Running the Node.js application.

If you have not installed the required npm modules, go ahead and install them by running

npm install

then,

node index.js

You should see, “Your server is running on http://localhost:3000”.

You can fire up your preferred web browser and go to http://your_server_ip:3000. It should show you your application’s default endpoint. For now, you can stop the server by pressing Cltr + C.

Configuring Nginx to act as a reverse proxy to serve our application:

We’ll make a copy and edit the default NGINX configuration, which is located at /etc/nginx/sites-available/default using the nano editor.

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/nodejs-deployment.conf
sudo nano /etc/nginx/sites-available/nodejs-deployment.conf

Then, we will paste the following code inside the server block.

server_name example.com www.example.com;

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;
}

You’ll have to replace server_name with your domain name. If your app is running on a different port other than 3000, you’ll have to change that too in the proxy_pass directive.

Make it persistent by creating a systemd unit

When you manually stop the server, Node applications typically shut down. Make it a default start-up service that will always start up in the event of any of the above-mentioned factors.

Use the following command to create a systemd service file:

sudo nano /lib/systemd/system/nodejs-deployment.service

Copy and paste the following code:

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

[Service]
Type=simple
User=YOUR_USERNAME_HERE
WorkingDirectory=/var/www/html/nodejs-deployment
Environment=NODE_ENV=production
ExecStart=/usr/bin/node index.js

Restart=always

[Install]
WantedBy=multi-user.target

Please update User, WorkingDirectory and ExecStart according to your needs.

Save and exit.

Activating services:

Run the following code to activate the systemd service that will run our Node.js app:

sudo systemctl daemon-reload
sudo systemctl start nodejs-deployment
sudo systemctl enable nodejs-deployment

Enable the nginx vhost by creating a symblink to the sites-enabled directory:

sudo ln -sf /etc/nginx/sites-available/nodejs-deployment.conf /etc/nginx/sites-enabled/nodejs-deployment.conf

Restart the server by running:

sudo service nginx restart

You can view the status of the service by running the following command on the console:

sudo systemctl status nodejs-deployment

Congratulations! 🎉

Your Node.js application is now deployed on your self hosted server.

Leave a Reply

Your email address will not be published. Required fields are marked *