Config_Backend

Backend Deployment

The backend is deployed on Amazon EC2. Here are the instructions to deploy a Node.js server on EC2 using Nginx and PM2:

1. Create an EC2 Instance

  • Go to the EC2 service in the AWS Management Console.

  • Click on Launch Instance.

  • Choose an Amazon Machine Image (AMI) (e.g., Ubuntu Server 20.04 LTS).

  • Select an instance type (e.g., t2.micro for basic use).

  • Create an key pair to connect for SSH access.

  • Configure security group rules to allow SSH (port 22), HTTP (port 80), and HTTPS (port 443) traffic.

  • Review and launch the instance.

  • Download the key pair (.pem file) for SSH access.

2. Connect to the EC2 Instance

To connect to the instance, go to the Connect tab in the AWS Management Console. You can connect using either EC2 Instance Connect or an SSH client.

For Ubuntu or macOS Users:

  1. Open an SSH client.

  2. Locate your private key file (e.g., awskey.pem).

  3. Run the following command to ensure your key is not publicly viewable:

    chmod 400 "awskey.pem"
    
  4. Connect to your instance using its Public DNS:

    ssh -i "awskey.pem" ubuntu@ec2-your-public-dns
    

For Windows Users (Using PowerShell):

  1. Open PowerShell.

  2. Navigate to the directory where your key file (awskey.pem) is stored.

  3. Run the following commands to configure the key permissions:

    icacls.exe awskey.pem /reset
    icacls.exe awskey.pem /grant:r "$($env:username):(r)"
    icacls.exe awskey.pem /inheritance:r
    
  4. Connect to your instance using its Public DNS:

    ssh -i "awskey.pem" ubuntu@ec2-your-public-dns
    

3. Set-Up your Server

  1. Configure UFW Firewall

    Ubuntu 20.04 servers can use the UFW (Uncomplicated Firewall) to ensure only connections to certain services are allowed. Here’s how to set up a basic firewall using UFW:

    Note

    If your servers are running on DigitalOcean, you can optionally use DigitalOcean Cloud Firewalls instead of UFW. It is recommended to use only one firewall at a time to avoid conflicting rules that may be difficult to debug.

    1. Check Available Applications

    Applications can register their profiles with UFW upon installation. These profiles allow UFW to manage these applications by name. OpenSSH, the service allowing you to connect to your server, has a profile registered with UFW. To see this, type:

    sudo ufw app list
    

    Output:

    Available applications:
      OpenSSH
    
    1. Allow SSH Connections

    To ensure that the firewall allows SSH connections so you can log back in next time, allow these connections by typing:

    sudo ufw allow OpenSSH
    
    1. Enable the Firewall

    Enable the firewall by typing:

    sudo ufw enable
    

    Type y and press ENTER to proceed.

    1. Verify Firewall Status

    To confirm that SSH connections are still allowed and check the firewall status, type:

    sudo ufw status
    

    Output:

    Status: active
    
    To                         Action      From
    --                         ------      ----
    OpenSSH                    ALLOW       Anywhere
    OpenSSH (v6)               ALLOW       Anywhere (v6)
    
  2. Install and Configure Nginx

    Step 1 – Installing Nginx

    Because Nginx is available in Ubuntu’s default repositories, you can install it using the apt packaging system.

    1. Update the local package index to ensure you have the most recent package listings:

      sudo apt update
      
    2. Install Nginx:

      sudo apt install nginx
      

      After accepting the procedure, apt will install Nginx and any required dependencies to your server.

    Step 2 – Adjusting the Firewall

    Before testing Nginx, adjust the firewall software to allow access to the service. Nginx registers itself as a service with UFW upon installation, making it straightforward to allow Nginx access.

    1. List the application configurations that UFW knows how to work with:

      sudo ufw app list
      

      Output:

      Available applications:
        Nginx Full
        Nginx HTTP
        Nginx HTTPS
        OpenSSH
      

      There are three profiles available for Nginx:

      • Nginx Full: Opens both port 80 (normal, unencrypted web traffic) and port 443 (TLS/SSL encrypted traffic).

      • Nginx HTTP: Opens only port 80 (normal, unencrypted web traffic).

      • Nginx HTTPS: Opens only port 443 (TLS/SSL encrypted traffic).

      It is recommended to enable the most restrictive profile that will still allow the traffic you’ve configured. For now, we will only need to allow traffic on port 80.

    2. Allow HTTP traffic by typing:

      sudo ufw allow 'Nginx HTTP'
      
    3. Verify the change by typing:

      sudo ufw status
      

      Output:

      Status: active
      
      To                         Action      From
      --                         ------      ----
      OpenSSH                    ALLOW       Anywhere
      Nginx HTTP                 ALLOW       Anywhere
      OpenSSH (v6)               ALLOW       Anywhere (v6)
      Nginx HTTP (v6)            ALLOW       Anywhere (v6)
      

    Step 3 – Checking Your Web Server

    At the end of the installation process, Ubuntu 20.04 starts Nginx. The web server should already be up and running.

    1. Check with the systemd init system to make sure the service is running:

      systemctl status nginx
      

      Output:

      ● nginx.service - A high performance web server and a reverse proxy server
         Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
         Active: active (running) since Fri 2020-04-20 16:08:19 UTC; 3 days ago
           Docs: man:nginx(8)
       Main PID: 2369 (nginx)
          Tasks: 2 (limit: 1153)
         Memory: 3.5M
         CGroup: /system.slice/nginx.service
                 ├─2369 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
                 └─2380 nginx: worker process
      

      This confirms that the service has started successfully.

    2. Test Nginx by requesting a page:

      Access the default Nginx landing page by navigating to your server’s IP address. If you do not know your server’s IP address, you can find it using the following command:

      curl -4 icanhazip.com
      

      When you have your server’s IP address, enter it into your browser’s address bar:

      http://your_server_ip
      

      You should receive the default Nginx landing page.

      Description of the image

    Step 4 – Managing the Nginx Process

    Now that you have your web server up and running, let’s review some basic management commands.

    1. Stop the Web Server

      To stop your web server, type:

      sudo systemctl stop nginx
      
    2. Start the Web Server

      To start the web server when it is stopped, type:

      sudo systemctl start nginx
      
    3. Restart the Web Server

      To stop and then start the service again, type:

      sudo systemctl restart nginx
      
    4. Reload the Configuration

      If you are only making configuration changes, Nginx can often reload without dropping connections. To reload Nginx, type:

      sudo systemctl reload nginx
      
    5. Disable Automatic Start at Boot

      By default, Nginx is configured to start automatically when the server boots. If you do not want this behavior, you can disable it by typing:

      sudo systemctl disable nginx
      
    6. Re-enable Automatic Start at Boot

      To re-enable the service to start up at boot, type:

      sudo systemctl enable nginx
      
  1. Installing Node.js

  1. **Install Node.js* 1. Install NodeSource PPA

    First, install the NodeSource PPA to access its contents. Make sure you’re in your home directory, and use curl to retrieve the installation script for the most recent LTS version of Node.js from its archives:

    cd ~
    curl -sL https://deb.nodesource.com/setup_20.x -o nodesource_setup.sh
    

    You can inspect the contents of this script with nano or your preferred text editor:

    nano nodesource_setup.sh
    
    1. Run the Installation Script

      After inspecting the script, run it under sudo:

      sudo bash nodesource_setup.sh
      

      The PPA will be added to your configuration, and your local package cache will be updated automatically.

    2. Install Node.js

      After running the setup script from NodeSource, install the Node.js package:

      $ sudo apt install nodejs
      
    3. Verify Node.js Installation

      To check which version of Node.js you have installed after these initial steps, type:

        node -v
      Output: v14.4.0
      

      Note: When installing from the NodeSource PPA, the Node.js executable is called nodejs, rather than node.

    4. Verify npm Installation

      The nodejs package contains the Node.js binary as well as npm, a package manager for Node modules, so you don’t need to install npm separately. Execute this command to verify that npm is installed and to create the configuration file:

        npm -v
      Output: 6.14.5
      
    5. Install Build Tools

      In order for some npm packages to work (those that require compiling code from source, for example), install the build-essential package:

      sudo apt install build-essential
      

    You now have the necessary tools to work with npm packages that require compiling code from source.

    With the Node.js runtime installed, let’s move on to writing a Node.js application.

  1. **Creating a Sample Application or Cloning a Project*

  1. Create a Sample Application

    To create a simple Node.js application, first navigate to your home directory and then create a new file using nano or your preferred text editor:

    cd ~
    nano hello.js
    

    Add the following code to hello.js:

    console.log('Hello, World!');
    

    Save and close the file. You now have a basic Node.js application.

  2. Clone an Existing Project

    Alternatively, you can clone an existing project from a repository using git. Replace httpsurl with the actual URL of the repository:

    git clone https://github.com/username/repository.git
    

    This will download the project files into a new directory.

    Step 3 — Installing PM2


Next, let’s install PM2, a process manager for Node.js applications. PM2 makes it possible to daemonize applications so that they will run in the background as a service.

  1. Install PM2

    Use npm to install the latest version of PM2 on your server:

    sudo npm install pm2@latest -g
    

    The -g option tells npm to install the module globally, so that it’s available system-wide.

  2. Run Your Application with PM2

    Let’s use the pm2 start command to run your application, hello.js, in the background:

    pm2 start hello.js
    

    This also adds your application to PM2’s process list, which is outputted every time you start an application:

    Output
    ...
    [PM2] Spawning PM2 daemon with pm2_home=/home/sammy/.pm2
    [PM2] PM2 Successfully daemonized
    [PM2] Starting /home/sammy/hello.js in fork_mode (1 instance)
    [PM2] Done.
    ┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
    │ id │ name               │ mode     │ ↺    │ status    │ cpu      │ memory   │
    ├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
    │ 0  │ hello              │ fork     │ 0    │ online    │ 0%       │ 25.2mb   │
    └────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
    

    As indicated above, PM2 automatically assigns an App name (based on the filename, without the .js extension) and a PM2 id. PM2 also maintains other information, such as the PID of the process, its current status, and memory usage.

  3. Set Up PM2 to Start on Boot

    Applications running under PM2 will be restarted automatically if the application crashes or is killed. However, to ensure the application launches on system startup, use the startup subcommand:

    pm2 startup systemd
    

    Run the command from the output, with your username in place of sammy:

    sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
    
  4. Save the PM2 Process List

    Save the PM2 process list and corresponding environments:

    pm2 save
    

    You have now created a systemd unit that runs PM2 for your user on boot. This PM2 instance, in turn, runs hello.js.

  5. Start the PM2 Service

    Start the service with systemctl:

    sudo systemctl start pm2-sammy
    

    Check the status of the systemd unit:

    systemctl status pm2-sammy
    

    PM2 provides many subcommands that allow you to manage or look up information about your applications:

    • Stop an application:

      pm2 stop app_name_or_id
      
    • Restart an application:

      pm2 restart app_name_or_id
      
    • List the applications currently managed by PM2:

      pm2 list
      
    • Get information about a specific application using its App name:

      pm2 info app_name
      
    • Monitor application status, CPU, and memory usage:

      pm2 monit
      

Step 4 — Setting Up Nginx as a Reverse Proxy Server

Your application is running and listening on localhost, but you need to set up a way for your users to access it. We will set up the Nginx web server as a reverse proxy for this purpose.

  1. Edit Nginx Configuration

    Open your Nginx configuration file for editing:

    sudo nano /etc/nginx/sites-available/example.com
    

    Within the server block, you should have an existing location / block. Replace the contents of that block with the following configuration:

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

    This configures the server to respond to requests at its root. Assuming our server is available at example.com, accessing https://example.com/ via a web browser would send the request to hello.js, listening on port 3000 at localhost.

  2. Optional: Add Additional Location Blocks

    You can add additional location blocks to the same server block to provide access to other applications on the same server:

    server {
    ...
        location /app2 {
            proxy_pass http://localhost: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;
        }
    ...
    }
    

    This block allows access to another application running on port 3001 via https://example.com/app2.

  3. Test Nginx Configuration

    Make sure you didn’t introduce any syntax errors by typing:

    sudo nginx -t
    
  4. Restart Nginx

    Restart Nginx to apply the changes:

    sudo systemctl restart nginx