DEV Community

Arshan Nawaz
Arshan Nawaz

Posted on • Edited on

Deploy your mern stack app on VPS using nginx ( domain + subdomain)

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" 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

Create a New User on Ubuntu
Open a terminal on your Ubuntu server.
Add a new user:

adduser username 
Enter fullscreen mode Exit fullscreen mode

Add the new user to the sudo group to grant administrative privileges:

usermod -aG sudo username 
Enter fullscreen mode Exit fullscreen mode

Test New User's Login
Switch to the new user:

su - username
Enter fullscreen mode Exit fullscreen mode

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

sudo apt update 

Enter fullscreen mode Exit fullscreen mode

Upgrade the installed packages:

sudo apt upgrade 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
ufw allow OpenSSH
sudo ufw status
sudo ufw allow 22    # Allow SSH
sudo ufw allow 80    # Allow HTTP
sudo ufw allow 443   # Allow HTTPS
sudo ufw enable      # Enable UFW
sudo ufw status      # Check UFW status after enabling
sudo ufw reload      # Reload UFW to apply rules
Enter fullscreen mode Exit fullscreen mode

Install Node.js

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

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

Enter fullscreen mode Exit fullscreen mode

Install Node.js:


sudo apt-get install -y nodejs 
Enter fullscreen mode Exit fullscreen mode

Verify the Node.js installation:

node --version 
npm -version
Enter fullscreen mode Exit fullscreen mode

Install Nginx


sudo apt install nginx 
Enter fullscreen mode Exit fullscreen mode

Test the Nginx configuration:

sudo nginx -t 
Enter fullscreen mode Exit fullscreen mode

Start Nginx:

sudo systemctl start nginx

Enter fullscreen mode Exit fullscreen mode

Go into a /var/www directory:

sudo cd /var/www
Enter fullscreen mode Exit fullscreen mode

Create a new folder named project-name

sudo mkdir project-name
Enter fullscreen mode Exit fullscreen mode

Give sudo username permissions to this newly created folder.

sudo chown -R username: username /var/www/project-name
Enter fullscreen mode Exit fullscreen mode

Create a frontend folder project.com

sudo mkdir project.com
Enter fullscreen mode Exit fullscreen mode

create a backend folder named api.project.com

sudo mkdir api.project.com
Enter fullscreen mode Exit fullscreen mode

create a admin folder named admin.project.com

sudo mkdir admin.project.com
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Run command to clone frontend repo

git clone <repo-url> .
Enter fullscreen mode Exit fullscreen mode

Now after cloning the frontend

npm install 
Enter fullscreen mode Exit fullscreen mode
sudo nano .env
Enter fullscreen mode Exit fullscreen mode

Extra step for react folder

npm run build
Enter fullscreen mode Exit fullscreen mode

Now to the backend folder name api.project.com

sudo cd /var/www/project-name/api.project.com
Enter fullscreen mode Exit fullscreen mode

Run command to clone backend repo

git clone <repo-url> .
Enter fullscreen mode Exit fullscreen mode

Now after cloning the backend

npm install
Enter fullscreen mode Exit fullscreen mode
sudo nano .env
Enter fullscreen mode Exit fullscreen mode

Now go to the admin folder name admin.project.com

sudo cd /var/www/project-name/admin.project.com
Enter fullscreen mode Exit fullscreen mode

Run command to clone admin repo

git clone <repo-url> .
Enter fullscreen mode Exit fullscreen mode

Now after cloning the admin

npm install 
Enter fullscreen mode Exit fullscreen mode
sudo nano .env
Enter fullscreen mode Exit fullscreen mode

Extra step for react folder

npm run build
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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;

    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
    }
}
Enter fullscreen mode Exit fullscreen mode

Enable the site by creating a symbolic link:

sudo ln -s /etc/nginx/sites-available/project.com /etc/nginx/sites-enabled/ 
Enter fullscreen mode Exit fullscreen mode

Test the Nginx configuration:

sudo nginx -t 
Enter fullscreen mode Exit fullscreen mode

Restart Nginx:

sudo systemctl restart nginx 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:9000;
        # Add other proxy-related settings if needed
    }
}
Enter fullscreen mode Exit fullscreen mode

Enable the site by creating a symbolic link:

sudo ln -s /etc/nginx/sites-available/api.project.com /etc/nginx/sites-enabled/ 
Enter fullscreen mode Exit fullscreen mode

Test the Nginx configuration:

sudo nginx -t 
Enter fullscreen mode Exit fullscreen mode

Restart Nginx:

sudo systemctl restart nginx 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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;

    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
    # }
}
Enter fullscreen mode Exit fullscreen mode

Enable the site by creating a symbolic link:

sudo ln -s /etc/nginx/sites-available/admin.project.com /etc/nginx/sites-enabled/ 
Enter fullscreen mode Exit fullscreen mode

If you have just server IP, not domain

# /etc/nginx/sites-available/myapp
server {
    listen 80;
    server_name server_ip;

    # Serve Main React App
    location / {
        root /var/www/html/role-permission-client-build;  # Path to your main React app's build directory
        try_files $uri /index.html;
    }

# Serve Admin React App
    location /admin/ {
        alias /var/www/admin-build;  # Path to your admin React app's build directory
        try_files $uri /admin/index.html;
    }

    # Proxy API Requests
    location /api/ {
        proxy_pass http://localhost:9000;  # Backend API server
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # Optional: Handle 404 errors
    error_page 404 /404.html;
    location = /404.html {
        root /var/www/html/role-permission-client-build;  # Path to your custom 404 page
    }
}
Enter fullscreen mode Exit fullscreen mode

Then for server-ip nginx

sudo ln -s /etc/nginx/sites-available/my-app /etc/nginx/sites-enabled/
Enter fullscreen mode Exit fullscreen mode

Test the Nginx configuration:

sudo nginx -t 
Enter fullscreen mode Exit fullscreen mode

Restart Nginx:

sudo systemctl restart nginx 
Enter fullscreen mode Exit fullscreen mode

Install PM2 to Manage Your Node.js Application
Install PM2

sudo npm install pm2 -g
Enter fullscreen mode Exit fullscreen mode

Start Your Application with PM2

pm2 start api.project.com/server.js
Enter fullscreen mode Exit fullscreen mode

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 )
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Check Status of Certbot

sudo systemctl status certbot.timer
Enter fullscreen mode Exit fullscreen mode

Dry Run SSL Renewal

sudo certbot renew --dry-run
Enter fullscreen mode Exit fullscreen mode

Top comments (0)