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.
Post Contents
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.