How to Deploy Node.js Backend with React Frontend and SQL Database on CyberPanel (The Ultimate Guide)

deploy-nodejs-react-express-sql-cyberpanel

0 comments

Why CyberPanel for MERN Stack?

Most tutorials assume you need a VPS with Nginx or Apache alone. But if you already love the ease of CyberPanel (OpenLiteSpeed), you don’t need to switch. You can host a React/Vite frontend, an Express.js backend, and a MySQL database on the same domain.

However, there is a catch: CyberPanel’s default setup doesn’t run Node.js persistently. We will fix that using PM2 and a custom vhost configuration.

In this guide, I will walk you through the exact process I use to deploy:

  • Frontend: React (or Vite + React)
  • Backend: Node.js + Express
  • Database: MySQL (via CyberPanel DB wizard)

Prerequisite

  • CyberPanel installed on a VPS/Dedicated server.
  • Root or Sudo access via SSH.
  • A domain pointed to your server (e.g., test.aarshpatel.me)

Step 1: Create the Website in CyberPanel

  1.  First, log in to your CyberPanel dashboard.
  2.  Go to Websites → Create Website.
  3.  Enter your domain (e.g., yourdomain.com).
  4.  Choose Package, User, Email, PHP (any version – it doesn’t matter, we will override it).
  5.  Select SSL (force HTTPS later).
  6.  Click Create.

This creates the document root at:
/home/yourdomain.com/public_html/

Step 2: Install NVM, Node.js, and PM2

CyberPanel may have an older Node version. Let’s install NVM (Node Version Manager).
First, login to SSH and switch root user to website’s user. to know what is your website username we will check /etc/passwd file. I got to know my website’s username is test1234. now switch to the website’s user and install NVM, Node.js and pm2 in it.
cat /etc/passwd
su - test1234
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

export NVM_DIR="$HOME/.nvm"
       [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

source ~/.bashrc
nvm install 22
nvm alias default 22
nvm list
nvm ls
nvm use 22

#install pm2
npm install pm2@latest -g

#=========To KEEP NVM PERSISTANT FOR USER=========
#Verify NVM is installed
ls ~/.nvm

#Force-load NVM on EVERY SSH session
nano ~/.bashrc

#ADD AT THE VERY BOTTOM
export NVM_DIR="$HOME/.nvm"
       [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

#Save & exit.

#Create .bash_profile (CRITICAL step)
nano ~/.bash_profile

#Add:
source ~/.bashrc

#Save & exit.

#Reload shell manually (once)
source ~/.bashrc

Check:
nvm --version
node -v
pm2 -v
Great, we have installed nvm, node and pm2 persistent on our website’s user.

Step 3: Upload Frontend (React) to public_html/

On your local machine, build your React app:

cd /home/yourdomain.com/public_html/frontend/
npm install
npm audit fix --force
npm run build

This generates a dist/ (Vite) or build/ (CRA) folder.

Move dist/* or build/* files to public_html and delete the frontend folder and zip:

  1.  Now go to filemanager in CyberPanel and move your dist/* or build/* files to public_html/
  2.  Next, delete frontend.zip and frontend/ folder which is not needed. We already have frontend build files which we needed to host in public_html.
  3.  Now select all the files and fix permissions.
  4.  Important: For React Router (client-side routing), you will need a .htaccess file (covered in Step 7).

Step 4: Create/Upload Backend Directory

We will keep the backend outside public_html for security.

upload  your backend.zip or backend folder outside the public_html (excluding node_modules). I prefer to upload zip of backend directory filemanager. It saves your time to upload one zip file insted of uploading multiple files.

Now unzip the backend.zip. Go to backend/ folder and select all files and fix permissions. Next, we have to install the node_modules. Access your SSH again and run:

cd /home/yourdomain.com/backend/
npm install
npm audit fix --force

Step 5: Create Database in CyberPanel

Go to Databases → Create Database.

Enter:

  • Database Name: app_db
  • Username: app_user
  • Password: “strong_db_password”
  • Click Create.

Step 6: Configure.env File in Backend

Inside /home/yourdomain.com/backend/.env:

PORT=5000
DB_HOST=localhost
DB_USER=app_user
DB_PASSWORD='YourStrongPassword'
DB_NAME=app_db
NODE_ENV=production

Step 7: Start Backend with PM2

cd /home/yourdomain.com/backend
pm2 start index.js --name yourdomain-api --watch   
#(if you have server.js then replace it with index.js)
pm2 list
#Make PM2 restart on server reboot:
pm2 save && pm2 startup

Step 9: Edit CyberPanel vHost.conf (Virtual Host Config)

Go to websites -> List Websites -> click Manage near yourdomain.com -> Select vhost.conf -> Edit at very bottom of file and save.

extprocessor testaarsh {
type proxy
address 127.0.0.1:5000   (port should be same in backend/.env and backend/server.js or index.js
maxConns 100
pcKeepAliveTimeout 60
initTimeout 60
retryTimeout 0
respBuffer 0
}

context /api {      #(if you are using /api inside your node.js app then make it /api else only / )
type proxy
handler testaarsh
addDefaultCharset off
}

Done you have successfully completed your vhost nodeJS proxy setup. Now we have to setup .htaccess rules in your frontend to use this nodejs backend proxy we setted up. This is important step if not done your frontend will not talk/connect with your backend.

Remember vHost rules and .htaccess rules are very important for routing request from frontend to backend. vHost rules depends how you have created your application have you used /api or not? It varies. If this rule doesnot work you can take help of AI tools to create vhost and .htaccess rules. If that too doesnot work you can comment on this post and i will try to help you with it.

Step 10: Configure .htaccess for React Routing

Go to websites -> List Websites -> click Manage near yourdomain.com -> Select .htaccess -> Edit the file and save

RewriteEngine On

# Proxy /api requests to Node.js backend
RewriteRule ^api/(.*)$ http://127.0.0.1:5095/api/$1 [P,L]

# Serve static files as-is
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]

# Fallback to index.html for React Router
RewriteRule ^ /index.html [L]

Step 11: Restart PM2 and lsws and we are done 🙂

systemctl restart lsws
pm2 restart yourdomain-api

Now visit:

https://yourdomain.com → Should show your React app

🎉 Your full-stack app is live!

Troubleshooting Common Issues

Issue Solution
API 404 Check if PM2 is running: pm2 list
React routes don’t work Verify .htaccess is in public_html/ and vhost.conf and proxy ports
DB connection fails Check .env and run mysql -u app_user -p
Port 5000 in use Change PORT in .env , change in index.js/server.js and update vhost.conf

If you change any settings and save it, don’t forgot to restart pm2 and lsws.

Why am i using Cyberpanel?

It provides me full access of root. I can deploy on any type of VPS/Cloud/VDS/Dedicated servers as per my need. I can increase/decrease the server configurations as per need. Cyberpanel supports Docker if i need. I can secure server myself by implementing proper firewalls, ModSecurity configs, etc. Basically, i can manage whole hosting infrastructure. feel free to reach me out at [email protected]

Related Posts

Leave a Comment