Complete Path For Deploying Project On Digital-Ocean

With R2, Nginx, Redis, Node.js

To deploy node.js project, at the very first you have to buy a droplet or an instance on the digital ocean and make non-root user, below i have shared some screenshots of buying a droplet and creating a non-root user.

In above screenshot, there is a create button, after clicking this button you have to select droplet and then you will get following screen.

select your prefered server, OS, give name to your droplet.

select your prefered plan and setup ssh keys to have passwordless login.

ssh setup :- 1)open your local terminal and type “ssh-keygen”.

2) click on “add new ssh key”.

3) copy and paste key created on your local machine and save this.

click on “create droplet”

then your drplet will be created, you will get your droplets IP.

now open your droplet’s console.

you will get logged in as root user.

now we will create non-root user with sudo permissions, we will do everything in future using this user.

type “adduser $userName”.

Granting Administrative Permissions to non-root user

type “usermod -aG sudo $userName”.

Now, when logged in as your regular user, you can type sudo before commands to run them with superuser privileges.

now we’r done with basic things,

now you will need a Domain name pointed to your droplet’s IP address.

now we will install NginX.

NginX

Since this is our first interaction with the apt packaging system in this session, we will update our local package index so that we have access to the most recent package listings. type “sudo apt update” in the console.

Now, we can install Nginx using this command : “sudo apt install nginx”.

after this apt will install Nginx and any required dependencies to your server.

Adjusting nginx firewall:-

Before testing Nginx, the firewall software needs to be adjusted to allow access to the service, nginx by default registers it-self as service.

List the application configurations by typing, "sudo ufw app list”

you should get output like given below.

Available applications:
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
  OpenSSH
  • Nginx HTTP: This profile opens only port 80 (normal, unencrypted web traffic)

  • Nginx HTTPS: This profile opens only port 443 (TLS/SSL encrypted traffic)

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

you can allow any traffic profile that you want by typing

“ sudo ufw allow ‘Nginx HTTP’ ”

In our case we will use http and https both so we are going to use full access. by command

“ sudo ufw allow ‘Nginx Full’ ”

You can verify the change by typing:

“ sudo ufw status ”

We can check with the systemd init system to make sure the service is running by typing:

systemctl status nginx

this command will give you output like shown below :

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

Now you can check if the nginx is working on browser,

Just search following line on browser :- “ https://your_server_ip

you will get default Nginx landing page

let’s take a look at some basic management commands :

To stop nginx server : “sudo systemctl stop nginx”

To start nginx server : “sudo systemctl start nginx”

To restart nginx server : “sudo systemctl restart nginx”

# setting up your domain name to the system

Nginx on Ubuntu 20.04 has one server block enabled by default that is configured to serve documents out of a directory at /var/www/html. While this works well for a single site, it can become unwieldy if you are hosting multiple sites. Instead of modifying /var/www/html, let’s create a directory structure within /var/www for our your_domain site, leaving /var/www/html in place as the default directory to be served if a client request doesn’t match any other sites.

Create the directory for your_domain as follows, using the -p flag to create any necessary parent directories:

sudo mkdir -p /var/www/$domainName/html

Next, assign ownership of the directory with the $USER environment variable:

sudo chown -R $USER:$USER /var/www/$domainName/html

The permissions of your web roots should be correct if you haven’t modified your umask value, which sets default file permissions. To ensure that your permissions are correct and allow the owner to read, write, and execute the files while granting only read and execute permissions to groups and others, you can input the following command:

“sudo chmod -R 755 /var/www/$domainName”

Next, create a sample index.html page using nano (text editor):

sudo nano /var/www/$domainName/html/index.html

and write some HTML code inthis file

eg.<html>
<head>
<title>Welcome!</title>
</head>
<body>
<h1>Success! Your domain is working!</h1>
</body>
</html>

Save and close the file by pressing Ctrl+X to exit, then when prompted to save, Y and then Enter.

In order for Nginx to serve this content, it’s necessary to create a server block with the correct directives.

let’s make a new configuration at /etc/nginx/sites-available/$domainName:

sudo nano /etc/nginx/sites-available/$domainName

this will create and open configuration file paste in the following content to the file.

server {
listen 80;
listen [::]:80;

root /var/www/your_domain/html;
index index.html index.htm index.nginx-debian.html;

server_name your_domain www.your_domain;

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

Notice that we’ve updated the root configuration to our new directory, and the server_name to our domain name.

Next, let’s enable the file by creating a link from it to the sites-enabled directory, which Nginx reads from during startup:

sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/

To avoid a possible hash bucket memory problem that can arise from adding additional server names, it is necessary to adjust a single value in the /etc/nginx/nginx.conf file. Open the file:

sudo nano /etc/nginx/nginx.conf

Find the server_names_hash_bucket_size directive and remove the # symbol to uncomment the line. If you are using nano, you can quickly search for words in the file by pressing CTRL and w.

Now after editing this file check for syntax errs by command :

sudo nginx -t”

Restart nginx to enable changes.

sudo systemctl restart nginx

now we have to install certbot for using https (secured) connection.

type : “sudo apt install certbot python3-certbot-nginx

after installing certbot successfully,

let’s run Certbot and fetch our certificates. in order to use https protocol

type :“sudo certbot — nginx -d yourDomain.com -d yourDomain.com

This runs certbot with the --nginx plugin, using -d to specify the domain names we’d like the certificate to be valid for.

If this is your first time running certbot, you will be prompted to enter an email address and agree to the terms of service. After doing so, certbot will communicate with the Let’s Encrypt server, then run a challenge to verify that you control the domain you’re requesting a certificate for.

If that’s successful, certbot will ask how you’d like to configure your HTTPS settings.

# Auto Renewal of certificates

Let’s Encrypt’s certificates are only valid for ninety days. This is to encourage users to automate their certificate renewal process. The certbot package we installed takes care of this for us by adding a systemd timer that will run twice a day and automatically renew any certificate that’s within thirty days of expiration.

You can query the status of the timer with systemctl:

sudo systemctl status certbot.timer

To test the renewal process, you can do a dry run with certbot:

sudo certbot renew — dry-run

If you see no errors, you’re all set.

Now visit your domain name on browser.

Now we are all set to clone and run our node.js project.

type “cd” to get on root directory of current user.

now we will make folder called /apps and save our projects to this folder.

for that type “mkdir apps” and “cd apps

now we are into apps folder.

clone your project with ssh keys, (why ssh keys --> when we have to update our code then everytime we will be asked for password if its not cloned with ssh to avoid this we will clone project with ssh key)

by generating ssh key on droplet’s console,

by typing “ssh-keygen

copy the ssh key and paste in your gitlab’s account (gitlab, github, bitbucket).

now copy ssh url of project, and clone on console,

by typing “git clone YOUR_URL

# Installing node.js

First, install the NodeSource PPA in order to get access to 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
deb.nodesource.com/setup_14.x -o nodesource_setup.sh

nano nodesource_setup.sh

sudo bash nodesource_setup.sh

sudo apt install nodejs

node -v

npm -v

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

sudo apt install build-essential

# Installing PM2

sudo npm install pm2@latest -g

Applications that are running under PM2 will be restarted automatically if the application crashes or is killed, but we can take an additional step to get the application to launch on system startup using the startup subcommand. This subcommand generates and configures a startup script to launch PM2 and its managed processes on server boots:

pm2 startup systemd

replace YOUR_USERNAME with your user’s name.

sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u YOUR_USERNAME — hp /home/YOUR_USERNAME

pm2 save

Start the service with systemctl:

sudo systemctl start pm2-YOUR_USERNAME

Check the status of the systemd unit:

systemctl status pm2-YOUR_USERNAME

now go into your projects directory using “cd your_Project”

and run your project using pm2 by typing :

pm2 start npm --name "app name" -- start

now your project is running on some port note that PORT_NUMBER.

and goto nginx configuration file that we created earlier

“sudo nano /etc/nginx/sites-available/YOUR_DOMAIN.com

Within the server block, you should have an existing location / block. Replace the contents of that block with the following configuration. If your application is set to listen on a different port, update the highlighted portion to the correct port number:

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;
    }
...

if you have multiple project running on single domain with diff. port number then,

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;
    }
    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;
    }
...
}

Once you are done adding the location blocks for your applications, save the file and exit your editor.

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

sudo nginx -t

sudo systemctl restart nginx

you’r done visit your domain name with correct port and you can see your project up and running.

your Node.js application is running

Did you find this article valuable?

Support Nilesh Kharad by becoming a sponsor. Any amount is appreciated!