Setting Up Nginx to Run Multiple Node.js App on AWS EC2 Instance

Prerequisite

Earlier before, if you’re following a post about install nginx on AWS EC2, you’ll have a server configuration file called like example.com, for me is api.budidev.com, it’s configured to listen default port 80, which is default port for HTTP connection.

And then if you’re following another post about secure HTTPS connection on nginx, the configuration file will be edited automatically by Certbot to configure HTTPS connection that listen on port 443, and it’s configured to redirect all HTTP traffic to secure HTTPS.

The end result of configuration file api.budidev.com look like this:

server {
  root /var/www/api.budidev.com/html;
  index index.html index.htm index.nginx-debian.html;

  server_name api.budidev.com;

  location / {
    try_files $uri $uri/ =404;
  }

  listen [::]:443 ssl ipv6only=on; # managed by Certbot
  listen 443 ssl; # managed by Certbot
  ssl_certificate /etc/letsencrypt/live/api.budidev.com/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/api.budidev.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 {
  if ($host = api.budidev.com) {
    return 301 https://$host$request_uri;
  } # managed by Certbot

  listen 80;
  listen [::]:80;

  server_name api.budidev.com;
  return 404; # managed by Certbot
}

One more for prerequisite, if you’re following previous post about install node.js and make node.js app keep running, you’ll have a node.js app that running on some port, for me is port 3000.

Update api.budidev.com

Before we begin to talk about run multiple node.js app, I’ll update the configuration file to route HTTP and HTTPS connection to the Node.js app that running on port 3000, so I can access Node.js app by navigating to https‎://api.budidev.com, and no needed to specify the port again, like https‎://api.budidev.com:3000.

Connect to your instance first, then open the configuration file:

sudo nano /etc/nginx/sites-available/api.budidev.com

Update the file with the content below

server {
  root /var/www/api.budidev.com/html;
  index index.html index.htm index.nginx-debian.html;

  server_name api.budidev.com;

  # --- UPDATE CONFIGURATION HERE ---
  location / {
    # try_files $uri $uri/ =404;
    proxy_pass http://127.0.0.1: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;
  }
  # ----------------------------------  

  listen [::]:443 ssl ipv6only=on; # managed by Certbot
  listen 443 ssl; # managed by Certbot
  ssl_certificate /etc/letsencrypt/live/api.budidev.com/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/api.budidev.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 {
  if ($host = api.budidev.com) {
    return 301 https://$host$request_uri;
  } # managed by Certbot

  listen 80;
  listen [::]:80;

  server_name api.budidev.com;
  return 404; # managed by Certbot
}

Notice here that my configuration file name and my server_name is api.budidev.com, you should replace with your own like example.com, and notice too that I run node.js app on port 3000, replace this with your own port that run node.js app, close and save after editing.

Test nginx configuration

sudo nginx -t

If there aren’t any problems, restart nginx to enable changes

sudo service nginx restart

Now if you’re going to your domain or subdomain name, for me is https://‎api.budidev.com without adding specific port like 3000, you should see node.js app show up:

api.budidev.com

api.budidev.com

Run Multiple Node.js App

I found 2 approach to run multiple node.js app in one server, you can choose which one you’re preferred.

First Approuch

The first approach is, you can update and add a new location on your configuration file before, for example, I’ll edit my configuration file api.budidev.com

  1. Create and run a new node.js app on some port, for example port 3001, look at a post about install node.js and make node.js app keep running for detail

  2. Update api.budidev.com

server {
  root /var/www/api.budidev.com/html;
  index index.html index.htm index.nginx-debian.html;

  server_name api.budidev.com;

  location / {
    proxy_pass http://127.0.0.1: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;
  }

  # --- ANOTHER NODE.JS APP HERE ---
  location /app2/ {
    proxy_pass http://127.0.0.1:3001/;
    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;
  }  
  # ---------------------------------

  listen [::]:443 ssl ipv6only=on; # managed by Certbot
  listen 443 ssl; # managed by Certbot
  ssl_certificate /etc/letsencrypt/live/api.budidev.com/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/api.budidev.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 {
  if ($host = api.budidev.com) {
    return 301 https://$host$request_uri;
  } # managed by Certbot

  listen 80;
  listen [::]:80;

  server_name api.budidev.com;
  return 404; # managed by Certbot
}

In this approuch, the second node.js app will run on route /app2, for me is https://‎api.budidev.com/app2

Second Approuch

The second approach is, you can run another your node.js app on new domain or subdomain, for example:

  1. Create domain or subdomain called sub.example.com using A Record and pointing this to IP Address of your AWS EC2 instance
  2. Create and run a new node.js app on some port, for example port 3001, look at a post about install node.js and make node.js app keep running for detail
  3. Create new nginx server block configuration file called sub.example.com, and use proxy_pass to route to your node.js app on port 3001, like the example above
  4. Secure your domain or subdomain using Let’s Encrypt, look at a post about secure https connection in nginx for detail

#nginx   #nodejs   #aws   #server