DEV Community

Amjad C P
Amjad C P

Posted on • Edited on

Host NodeJS Server in EC2 Instance

EC2 instance is a cloud computing service provided by AWS. It allows you to launch virtual machines called instances. In this case, we will be hosting our Node.js server on an EC2 instance. Before proceeding, make sure you have AWS access set up as a prerequisite.

1. Launch EC2 Instance

  1. Click the "Launch Instance" button on the EC2 dashboard under Instances.

  2. Select an operating system (OS) from the available Amazon Machine Images (AMI). Ubuntu is recommended for learning purposes.

  3. Choose an instance type (t2.micro is recommended for learning purposes). The instance type determines the configuration of CPU, memory, storage, and network capacity for the EC2 instance. When selecting an instance type for production, you need to consider various factors such as the size of the server, the services to be provided, the expected number of users per minute, performance requirements, cost, and availability, among others. Refer to this link for guidance on choosing the appropriate instance type for your needs.

  4. Generate a new key pair (.pem file) and securely save it. You will need this file to access the EC2 instance through an SSH connection.

  5. Allow HTTP and HTTPS traffic, and temporarily set SSH access from everywhere. If you wish to restrict SSH access to your instance, either disable SSH or provide access to a static IP of another EC2 instance that allows SSH access everywhere.

  6. Leave the remaining options as default and click on "Launch Instance".
    AWS Task 1: Launch an EC2 instance

2.Assign Elastic IP to EC2 Instance

Elastic IP is the static public IP provided by AWS. By assigning the static IP to an instance, we can ensure that the IP won't change in the event of any failures occurring to the instance.

  1. Click the "Allocate Elastic IP address" button located in the EC2 dashboard under Elastic IPs.

  2. Leave all options as default and click on "Allocate".

  3. Associate the EC2 instance with the elastic IP.

3. Establish Remote Access to EC2 Instance through SSH

  1. Open terminal in your system and type the command :

    sudo ssh -i "path/to/.pem/file" ubuntu@<elastic ip assign to the instance>

  2. Update the package list : sudo apt-get update

  3. Upgrade the pages : sudo apt-get upgrade

4. Clone GitHub Repository

To clone a GitHub repository, you can use the SSH URL. However, before doing so, you need to set up a deploy key in the repository settings. Please note that you must have admin access to the repository in order to change the settings.

A deploy key is an SSH key that grants access to a single repository. To generate a deploy key, you can do so on your server and then add it to your repository settings on GitHub. By doing this, you will be able to securely clone the repository using the SSH URL.

For more information, please refer to this link.

  1. Generate the SSH key :

    a. ssh-keygen -t ed25519 -C "[your_email@example.com](mailto:your_email@example.com)"

    b. give the repository name for the SSH key ( recommended ) and store the key in the path /home/ubuntu/.ssh/<repository_name>

    c. create a file โ€œconfigโ€ in the path /home/ubuntu/.ssh/config and set the configuration

    Host <repository_name>
            Hostname github.com
            IdentityFile=/home/ubuntu/.ssh/<repository_name>
    

    d. Copy the value from /home/ubuntu/.ssh/<repository_name> and set as deploy key in repository settings

    e. clone the repository to the instance : git clone git@<repository_name>:<github_username>/<repository_name>

5. Install NodeJS

  1. install npm sudo apt-get install npm

  2. Install the package n using npm sudo npm install -g n

  3. Install node latest version sudo n stable

6. Run NodeJS server using PM2

PM2 is a production process manager to keep your application alive forever

  1. Open the repository in instance cd <repository_name>

  2. Install project packages npm ci

  3. Install PM2 sudo npm install -g pm2

  4. Start server sudo pm2 start /path/of/main/file.js --name <server_name>

7. Configure Nginx

Nginx will act as a reverse proxy for your server. Before configuring Nginx, you need to connect a domain to the EC2 instance. You can learn more about reverse proxy here.

  1. Install nginx : sudo apt-get install nginx

  2. Unlink the default configuration file sudo unlink /etc/nginx/sites-enabled/**def**ault

  3. Create new configuration file sudo nano /etc/nginx/sites-available/reverse-proxy.conf

    server {
        listen 80;
        server_name <YOUR_PUBLIC_IP_ADDRESS / DOMAIN_NAME>;
        access_log /var/log/nginx/reverse-access.log;
        error_log /var/log/nginx/reverse-error.log;
        location / {
            proxy_pass [http://localhost:](http://localhost:5000/)<server_port>;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
    
  4. Link the new configuration file

    sudo ln -s /etc/nginx/sites-available/reverse-proxy.conf /etc/nginx/sites-enabled/reverse-proxy.conf

  5. Check is there any issue in the new configuration syntax sudo nginx -t

  6. Restart the nginx service sudo systemctl reload nginx

8. Configure SSL Certificate using Certbot

  1. Install certbot sudo apt install certbot python3-certbot-nginx

  2. Request for SSL certificate sudo certbot --nginx -d YOUR_DOMAIN

Note

When performing a task for the first time, it is possible that you may need to repeat certain steps multiple times. In such cases, there is a chance of exiting from a process without terminating it.

  1. To get a process ID / service ID lsof -t -i:<port>

  2. To kill a service kill service <id>

  3. Delete nginx sudo apt purge nginx nginx-common nginx-core

Top comments (2)

Collapse
 
mohasinkr profile image
Mohasin K R

Kudos for writing this article ๐Ÿ‘

Collapse
 
deepakmkoshy profile image
Deepak Mathews Koshy

Super helpful article, was able to get an EC2 instance up and running in under an hour. Adding screenshots would have been helpful though.