Deploy your mern stack app on DigitalOcean using nginx ( domain + subdomain)
Tags: beginners, react, devops, node
Published: 2024-03-13 06:55:32



Creating an account with DigitalOcean.
During creating a droplet, generate an SSH Key Pair after Open a terminal.
Run the command to generate a new SSH key pair:

```
ssh-keygen -t rsa -b 4096 -C "example@gmail.com" 
```
When prompted, save and name the key (press Enter to use the default location /Users/USER/.ssh/id_rsa).
Create and confirm a passphrase for the key (recommended for security).
This will generate two files: id_rsa and id_rsa.pub.
Add the Public Key
Display the public key using:

```
cat ~/.ssh/id_rsa.pub 
```
Copy the displayed public key.
Paste the public key into the SSH key content field on the platform or service where it's required (e.g., GitHub, Bitbucket).
Login using the root or default user of the server
Open terminal

```
ssh root@server_IP 
```
Create a New User on Ubuntu
Open a terminal on your Ubuntu server.
Add a new user:

```
adduser username 
```
Add the new user to the sudo group to grant administrative privileges:

```
usermod -aG sudo username 
```
Test New User's Login
Switch to the new user:

```
su - username
```

Now we will use sudo before any command
Update and Upgrade Packages
Update the package lists:

```
sudo apt update 

```
Upgrade the installed packages:

```
sudo apt upgrade 
```

#### Setting Up a Firewall
If your domain is registered, then both OpenSSH and Nginx Full will run. Otherwise, only Nginx HTTP will run. In Nginx Full mode, both HTTP and HTTPS are available.
```
ufw app list
```


```
ufw allow OpenSSH
```


```
ufw enable
```


```
ufw status
```



Install Node.js

Run the command to download and execute the Node.js setup script:

```
curl -fsSL https://deb.nodesource.com/setup_21.x | sudo -E bash - 

```
Install Node.js:

```

sudo apt-get install -y nodejs 
```
Verify the Node.js installation: 

```
node --version 
npm -version
```

Install Nginx

```

sudo apt install nginx 
```

Test the Nginx configuration:

```
sudo nginx -t 
```

Start Nginx:

```
sudo systemctl start nginx

```

Go into a /var/www directory:

```
sudo cd /var/www
```

Create a new folder named project-name

```
sudo mkdir project-name
```

Give sudo username permissions to this newly created folder.

```
sudo chown -R username: username /var/www/project-name
```
Create a frontend folder project.com

```
sudo mkdir project.com
```
create a backend folder named api.project.com

```
sudo mkdir api.project.com
```
create a admin folder named admin.project.com

```
sudo mkdir admin.project.com
```
Clone your repository of frontend, backend and admin in the required folder:
First, go to the frontend folder name project.com

```
sudo cd /var/www/project-name/project.com
```

Run command to clone frontend repo

```
git clone <repo-url> .
```

Now after cloning the frontend

```
npm install 
```

```
sudo nano .env
```
Extra step for react folder

```
npm run build
```
Now to the backend folder name api.project.com

```
sudo cd /var/www/project-name/api.project.com
```

Run command to clone backend repo

```
git clone <repo-url> .
```

Now after cloning the backend

```
npm install
```

```
sudo nano .env
```
Now go to the admin folder name admin.project.com

```
sudo cd /var/www/project-name/admin.project.com
```

Run command to clone admin repo

```
git clone <repo-url> .
```

Now after cloning the admin

```
npm install 
```

```
sudo nano .env
```
Extra step for react folder

```
npm run build
```
Configure Nginx for the project.com ( frontend )

Create and edit the Nginx server block file for your project.com:

```
sudo nano /etc/nginx/sites-available/project.com 
```
Insert the server block configuration as needed (use the provided example and adjust accordingly).

```
#. frontend project.com
server {
	listen 80;
	server_name domain.com www.domain.com or server_ip;
 
	location / {
    	root /var/www/project.com/build;
    	index index.html;
    	try_files $uri $uri/ /index.html;
# Ensure React Router works correctly
	}
 
	location /backend/ {
    	proxy_pass http://localhost:8000;
    	# 8000 is the backend app port 
	# Add other proxy-related settings if needed
	}
}
```

Enable the site by creating a symbolic link:

```
sudo ln -s /etc/nginx/sites-available/project.com /etc/nginx/sites-enabled/ 
```

Test the Nginx configuration:
 

```
sudo nginx -t 
```

Restart Nginx:
 

```
sudo systemctl restart nginx 
```
Configure Nginx for the API
Create and edit the Nginx server block file for your project.com:

```
sudo nano /etc/nginx/sites-available/api.project.com
```
 
Insert the server block configuration as needed (use the provided example and adjust accordingly).

```
#. backend api.project.com
server {
	listen 80;
	server_name api.domain.com ;
 
	location / {
    	proxy_pass http://localhost:8000;
    	# Add other proxy-related settings if needed
	}
}
```

Enable the site by creating a symbolic link:

```
sudo ln -s /etc/nginx/sites-available/api.project.com /etc/nginx/sites-enabled/ 
```

Test the Nginx configuration:
 

```
sudo nginx -t 
```

Restart Nginx:
 

```
sudo systemctl restart nginx 
```
If you have admin
Configure Nginx for the admin
Create and edit the Nginx server block file for your admin.project.com:


```
sudo nano /etc/nginx/sites-available/admin.project.com
```

 
Insert the server block configuration as needed (use the provided example and adjust accordingly).

```
# Admin admin.project.com

server {
    listen 80;
    server_name admin.domain.com or server_ip;

    location / {
        root /var/www/html/admin.project.com/build;
        index index.html;
        try_files $uri $uri/ /index.html; 
	# Ensure React Router works correctly
    }

    # Add other location blocks if needed for specific configurations

    # If you have a backend for the admin panel, you can configure it here
    # location /admin-backend/ {
    #     proxy_pass http://localhost:admin_backend_port;
    #     # Add other proxy-related settings if needed
    # }
}
```


Enable the site by creating a symbolic link:


```
sudo ln -s /etc/nginx/sites-available/admin.project.com /etc/nginx/sites-enabled/ 
```


Test the Nginx configuration:
 

```
sudo nginx -t 
```

Restart Nginx:
 

```
sudo systemctl restart nginx 
```


Install PM2 to Manage Your Node.js Application
Install PM2


```
sudo npm install pm2 -g
```

Start Your Application with PM2

```
pm2 start api.project.com/server.js
```


search your domain or server IP address on Google

whenever you update the code
log in using your root
then 

```
su - username ( If you have sudo user )
```

username = > new user you have created
then go to the frontend project.com folder run git pull and if any new package is installed then run the command
 

```
npm install 
```
and then make a new build if any change in code like in env change or code change, make a new build.
after that for the backend just pull the code and npm install, pm2 restart and nginx restarts.


**How to Enable free SSL in Your Domain Hosted on Remote Server or VPS ( only on domain if you have, not in server_ip )**

Install Certbot and it’s Nginx plugin

```
sudo apt install certbot python3-certbot-nginx
```


Verify Web Server Ports are Open and Allowed through Firewall
sudo ufw status verbose


Obtain an SSL certificate

```
sudo certbot --nginx -d your_domain.com -d www.your_domain.com -d api.your_domain.com -d admin.your_domain.com -d www.admin.your_domain.com
```

Check Status of Certbot

```
sudo systemctl status certbot.timer
```


Dry Run SSL Renewal

```
sudo certbot renew --dry-run
```