DEV Community

hussain mohammed
hussain mohammed

Posted on

Host Multiple Node Apps with nginx, pm2 with SSL certificate


Hey Developers,
If you're planning to host a Node.js application, or multiple Node.js applications, on a Linux server, consider this guide.
Before diving in, it's worth noting that there are various ways to set up a Node.js app with Nginx, and the abundance of documentation and YouTube videos can sometimes make the process confusing.
In my case, I launched an AWS EC2 instance with a Linux operating system. Let's assume the public IPv4 address of the EC2 instance, after attaching an Elastic IP address, is 11.111.111.111.

Step -1 

Connect to your instance using SSH 
Install the Nodejs, npm and PM2 using the below commands in the terminal

 sudo apt update
 sudo apt install nodejs npm
 sudo npm install -g pm2
Enter fullscreen mode Exit fullscreen mode

Max : What is PM2 for? 
PM2 is a renowned open-source process manager tailored for Node. js applications. It acts as a guardian, streamlining deployment, overseeing logs, monitoring resources, and ensuring minimal downtime for every application it manages.
https://pm2.keymetrics.io/

First, install the new Node.js applications or clone your existing Node.js repositories from your Git. Ensure both applications are running as per your requirements and are listening on different ports,
for example, ports "8000" and "8001".

Step -2

Next, start the Node.js applications with PM2. Navigate to the respective folders of each application and use PM2 to run them in the background, ensuring they will restart automatically if the server restarts.

cd /path/to/your/first/app
pm2 start app.js --name "app1"

cd /path/to/your/second/app
pm2 start app.js --name "app2"

pm2 save     # saves the running processes
                  # if not saved, pm2 will forget the running apps on next boot
Enter fullscreen mode Exit fullscreen mode

If you want pm2 to start on system boot

pm2 startup # starts pm2 on computer boot
Enter fullscreen mode Exit fullscreen mode

Step -3

Install Nginx and configure the Nginx file.
Command for installation

sudo apt install nginx
Enter fullscreen mode Exit fullscreen mode

Open the configuration file using the nano editor or any other editor that you are comfortable with. 

Max : Could you provide more information about the Nano editor? Due to client-imposed restrictions, I am unable to use any other text editors. Your insights would be greatly appreciated.

Nano is a nightmare for some Windows developers. However, GNU Nano is a text editor for Unix-like computing systems or operating environments using a command line interface. It emulates the Pico text editor, part of the Pine email client, and provides additional functionality. Unlike Pico, Nano is licensed under the GNU General Public License.
Cheatsheet for Nano: https://www.nano-editor.org/dist/latest/cheatsheet.html

Max : Can we use VSCode for this? 

If you're using Visual Studio Code (VS Code) for development, keep in mind that it doesn't have write permissions by default for folders outside the home directory on a Linux OS. You may need to install the appropriate VS Code extensions to manage these permissions effectively.

Extension name: "Save as Root in Remote - SSH"
Externsion URL: https://marketplace.visualstudio.com/items?itemName=yy0931.save-as-root

Devs who are using nano use the below command to open the file

sudo nano /etc/nginx/sites-available/default

Enter fullscreen mode Exit fullscreen mode

Replace the content with the following configuration, adjusting the domain names and ports accordingly:

  • NODEJS APP 1 -

server {
    listen 80;
    server_name subdomain1.yourdomain.com;

    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
Enter fullscreen mode Exit fullscreen mode
  • NODEJS APP 2 -
server {
    listen 80;
    server_name subdomain2.yourdomain.com;

    location / {
        proxy_pass http://localhost:8001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
Enter fullscreen mode Exit fullscreen mode

If you have only one node js application then, you can ignore "NODEJS APP2" in the above snippet and save it.
Check NGINX config:

sudo nginx -t

Enter fullscreen mode Exit fullscreen mode

Restart the nginx:

sudo service nginx restart

Enter fullscreen mode Exit fullscreen mode

Add your subdomain names (subdomain1.yourdomain.com & subdomain2.yourdomain.com) in Godaddy or Cloudflare etc as A record to your EC2 instance IP.

Step -4

Obtain SSL Certificates with Certbot:

sudo apt install certbot python3-certbot-nginx

Enter fullscreen mode Exit fullscreen mode

Run Certbot to obtain and install Free SSL certificates for your subdomains:

sudo certbot --nginx -d subdomain1.yourdomain.com -d subdomain2.yourdomain.com

Enter fullscreen mode Exit fullscreen mode

_ Max: If my case has only one domain, I will run the above command till sudo certbot - nginx -d subdomain1.yourdomain.com _
Yes, Perfecto! also, you don't have 2nd Server block in the below snippet.
Certbot should automatically update your Nginx configuration to include SSL settings. Ensure the new configuration looks like this:

server {
    listen 80;
    server_name subdomain1.yourdomain.com;

    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/subdomain1.yourdomain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/subdomain1.yourdomain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    listen 80;
    server_name subdomain2.yourdomain.com;

    location / {
        proxy_pass http://localhost:8001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/subdomain2.yourdomain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/subdomain2.yourdomain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
Enter fullscreen mode Exit fullscreen mode

Restart Nginx to apply the changes:

sudo systemctl restart nginx

Enter fullscreen mode Exit fullscreen mode

Now, your two Node.js applications should be accessible via https://subdomain1.yourdomain.com and https://subdomain2.yourdomain.com with SSL encryption.

Thank you !!!

Top comments (3)

Collapse
 
ra1nbow1 profile image
Matvey Romanov

Thanks a lot! Very nice and handy article

Collapse
 
andrea_from_italy profile image
andrea_fazzi

Thank you for your help and direction.
Very interesting and useful issue.
I'll need time to fully understand everything....