<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: hussain mohammed</title>
    <description>The latest articles on Forem by hussain mohammed (@hussain_mohammed).</description>
    <link>https://forem.com/hussain_mohammed</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1746461%2F8b38f1e2-3a33-4f93-91e0-cb2f19671430.png</url>
      <title>Forem: hussain mohammed</title>
      <link>https://forem.com/hussain_mohammed</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hussain_mohammed"/>
    <language>en</language>
    <item>
      <title>Host Multiple Node Apps with nginx, pm2 with SSL certificate</title>
      <dc:creator>hussain mohammed</dc:creator>
      <pubDate>Mon, 08 Jul 2024 10:29:17 +0000</pubDate>
      <link>https://forem.com/hussain_mohammed/host-multiple-node-apps-with-nginx-pm2-with-ssl-certificate-5dji</link>
      <guid>https://forem.com/hussain_mohammed/host-multiple-node-apps-with-nginx-pm2-with-ssl-certificate-5dji</guid>
      <description>

&lt;p&gt;Hey Developers,&lt;br&gt;
If you're planning to host a Node.js application, or multiple Node.js applications, on a Linux server, consider this guide.&lt;br&gt;
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.&lt;br&gt;
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.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step -1 
&lt;/h2&gt;

&lt;p&gt;Connect to your instance using SSH &lt;br&gt;
Install the Nodejs, npm and PM2 using the below commands in the terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; sudo apt update
 sudo apt install nodejs npm
 sudo npm install -g pm2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Max : What is PM2 for? &lt;/em&gt;&lt;br&gt;
&lt;em&gt;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.&lt;br&gt;
&lt;a href="https://pm2.keymetrics.io/" rel="noopener noreferrer"&gt;https://pm2.keymetrics.io/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;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,&lt;br&gt;
for example, ports "8000" and "8001".&lt;/p&gt;
&lt;h2&gt;
  
  
  Step -2
&lt;/h2&gt;

&lt;p&gt;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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want pm2 to start on system boot&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pm2 startup # starts pm2 on computer boot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step -3
&lt;/h2&gt;

&lt;p&gt;Install Nginx and configure the Nginx file.&lt;br&gt;
Command for installation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the configuration file using the nano editor or any other editor that you are comfortable with. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;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&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;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.&lt;br&gt;
&lt;strong&gt;Cheatsheet for Nano: &lt;a href="https://www.nano-editor.org/dist/latest/cheatsheet.html" rel="noopener noreferrer"&gt;https://www.nano-editor.org/dist/latest/cheatsheet.html&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Max : Can we use VSCode for this? &lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Extension name&lt;/strong&gt;: "Save as Root in Remote - SSH"&lt;br&gt;
&lt;strong&gt;Externsion URL&lt;/strong&gt;: &lt;a href="https://marketplace.visualstudio.com/items?itemName=yy0931.save-as-root" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/items?itemName=yy0931.save-as-root&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Devs who are using nano use the below command to open the file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/nginx/sites-available/default

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the content with the following configuration, adjusting the domain names and ports accordingly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NODEJS APP 1 -
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
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;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;NODEJS APP 2 -
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have only one node js application then, you can ignore "NODEJS APP2" in the above snippet and save it.&lt;br&gt;
Check NGINX config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nginx -t

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart the nginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo service nginx restart

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h2&gt;
  
  
  Step -4
&lt;/h2&gt;

&lt;p&gt;Obtain SSL Certificates with Certbot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install certbot python3-certbot-nginx

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run Certbot to obtain and install Free SSL certificates for your subdomains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo certbot --nginx -d subdomain1.yourdomain.com -d subdomain2.yourdomain.com

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart Nginx to apply the changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart nginx

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, your two Node.js applications should be accessible via &lt;a href="https://subdomain1.yourdomain.com" rel="noopener noreferrer"&gt;https://subdomain1.yourdomain.com&lt;/a&gt; and &lt;a href="https://subdomain2.yourdomain.com" rel="noopener noreferrer"&gt;https://subdomain2.yourdomain.com&lt;/a&gt; with SSL encryption.&lt;/p&gt;

&lt;p&gt;Thank you !!!&lt;/p&gt;

</description>
      <category>node</category>
      <category>pm2</category>
      <category>nginx</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
