Comprehensive Guide: Hosting and Deploying Multiple Node Applications on AWS EC2 with Step-by-Step Instructions

Comprehensive Guide: Hosting and Deploying Multiple Node Applications on AWS EC2 with Step-by-Step Instructions

Introduction:
Setting up and hosting a Node server on AWS EC2 can be a powerful and flexible solution for deploying your web applications. In this step-by-step guide, we will cover the entire process, from creating an EC2 instance to configuring Nginx with SSL certification for your domain. Let's dive into the details.

Creating an EC2 Instance:

  • Log in to your AWS Management Console.

  • Navigate to the EC2 dashboard and click on "Launch Instance."

  • Choose an Amazon Machine Image (AMI), select an instance type, configure instance details, add storage, configure security groups, and review your instance details.

  • Click "Launch," and select an existing key pair or create a new one. Download the .pem file, as you'll need it to connect to the EC2 instance later.

Connecting EC2 Instance with Elastic IP:

  • Allocate an Elastic IP from the AWS console.

  • Associate the Elastic IP with your EC2 instance to ensure a static IP address for your server. This is beneficial for maintaining a consistent connection, especially in a production environment.

Connecting to EC2 Instance using .pem file:

  • Open your terminal and navigate to the directory where the .pem file is located.

  • Use the following command to connect to your EC2 instance:
    ssh -i "your-key.pem" ec2-user@your-elastic-ip

Installing Git, NVM, and Setting Up Your Node.js Application:

  • Now that you're connected, it's time to prepare your environment:
    sudo yum update -y
    sudo yum install git -y
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash source ~/.bashrc

    nvm install node

  • Clone your Node.js server repository, install dependencies, set up the .env file, and start your application using PM2:
    git clone cd your-app-directory npm install cp .env.example .env pm2 start your-app.js

Creating an Nginx Server:

  • Install Nginx:
    sudo amazon-linux-extras install nginx1.12 sudo service nginx start

Nginx Configuration for HTTP:

Configuring SSL with Let's Encrypt:

  • Install Certbot and get SSL certificate:
    sudo amazon-linux-extras install epel
    sudo yum install certbot-nginx -y

    sudo certbot --nginx -d your-domain.com -d www.your-domain.com

  • Update Nginx configuration to include SSL:
    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/dev.usampac.org/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/dev.usampac.org/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 = dev.usampac.org) {
    return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    listen [::]:80;
    listen 443;
    listen [::]:443;
    server_name dev.usampac.org;
    return 404; # managed by Certbot

    }

Setting Up Nginx Routes for Multiple Servers:

  • Add location blocks for different routes:
    location /api {
    rewrite ^/api(/.*)$ $1 break;
    proxy_pass http://127.0.0.1:8000;
    # Additional proxy configurations
    }

    location /production/api {
    rewrite ^/production/api(/.*)$ $1 break;
    proxy_pass http://127.0.0.1:8020;
    # Additional proxy configurations
    }
    Putting it all together, if a request comes in with a URL path like /api/some/endpoint, the rewrite directive will modify it to /some/endpoint using the captured part after /api/. This adjusted URL is then passed to the proxied server specified in proxy_pass.

Enabling Ports in AWS Security Group:
In your EC2 dashboard, navigate to the security group associated with your instance and add inbound rules for ports 80 and 443.

Congratulations! You've successfully hosted your Node.js server on AWS EC2, secured it with SSL, and configured Nginx for optimal performance. This guide provides a solid foundation for deploying and maintaining web applications in a scalable and secure environment. Happy coding!

Sample Nginx.conf file, with ssl certificate.

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /run/nginx.pid;

include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    include /etc/nginx/conf.d/*.conf;

    server {
        server_name  example.com; 
        index   index.html;

        include /etc/nginx/default.d/*.conf;

        location /api {
            rewrite ^/api(/.*)$ $1 break;
            proxy_pass http://127.0.0.1:8000;
            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;
        }

        location /production/api {
            rewrite ^/production/api(/.*)$ $1 break;
            proxy_pass http://127.0.0.1:8020;
            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;
        listen 443 ssl;
        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    }

    server {
        if ($host = example.com) {
            return 301 https://$host$request_uri;
        }

        listen       80;
        listen       [::]:80;
        listen       443;
        listen       [::]:443;
        server_name  example.com;
        return 404;
    }
}