Choose Your Deployment Method
đ§
Method 1
Build on VM - Full setup with Node.js installation
âĄ
Method 2
Build Locally - Transfer artifacts only
âšī¸ Quick Comparison:
Method 1: Install Node.js on VM, build directly on server. Best for continuous deployment.
Method 2: Build on local machine, transfer files. Faster deployments, no build tools on server.
Method 1: Install Node.js on VM, build directly on server. Best for continuous deployment.
Method 2: Build on local machine, transfer files. Faster deployments, no build tools on server.
đĻ What You'll Need
- â Ubuntu VM with SSH access
- â Backend VM IP address
- â Your frontend project code
- â Basic terminal knowledge
⨠What You'll Deploy:
A production-ready React application with Nginx reverse proxy, optimized caching, and backend API integration.
A production-ready React application with Nginx reverse proxy, optimized caching, and backend API integration.
Method 1: Build on VM
1
Connect to Frontend VM
SSH into your Ubuntu virtual machine:
Bash
ssh user@your-frontend-vm-ip
2
Install Node.js 20.x
Install the latest LTS version of Node.js:
Bash
sudo apt update
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
node --version
npm --version
â
Expected Output:
Node version: v20.x.x
NPM version: 10.8.x
Node version: v20.x.x
NPM version: 10.8.x
3
Transfer Frontend Code
Option A: Using SCP (from Windows)
PowerShell
scp -r "E:\path\to\your-project" user@frontend-vm-ip:/home/user/
Option B: Using Git (on VM)
Bash
cd /home/user
git clone <your-repo-url>
4
Install Dependencies
Bash
cd /home/user/your-project
npm install
5
Configure Environment
Create and configure your .env file:
Bash
nano .env
Add this configuration:
ENV
VITE_API_URL=http://YOUR-BACKEND-VM-IP:8000
đĄ Save File: Press Ctrl+X, then Y, then Enter
6
Build Frontend
Bash
npm run build
â
Expected Output:
vite v5.0.0 building for production...
â built in 15.23s
This creates dist/public/ folder with production files.
vite v5.0.0 building for production...
â built in 15.23s
This creates dist/public/ folder with production files.
7
Install & Configure Nginx
Install Nginx web server:
Bash
sudo apt install -y nginx
Run this complete configuration script:
â ī¸ Important: Replace
<insert_Here_Backend_VM_pip> with your actual backend VM IP!
Bash Script
sudo bash << 'EOF'
cat > /etc/nginx/sites-available/default << 'NGINX'
upstream backend_api {
server <insert_Here_Backend_VM_pip>:8000 fail_timeout=0;
keepalive 32;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
client_max_body_size 10M;
location / {
root /var/www/html;
try_files $uri $uri/ /index.html;
add_header Cache-Control "no-cache, no-store, must-revalidate" always;
add_header Pragma "no-cache" always;
add_header Expires "0" always;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
root /var/www/html;
expires 30d;
add_header Cache-Control "public, immutable";
try_files $uri =404;
}
location /api/ {
proxy_pass http://backend_api;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
proxy_connect_timeout 10s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
NGINX
nginx -t && systemctl restart nginx && echo "â
nginx fixed!"
EOF
đ This script will:
â Create clean nginx config
â Test configuration
â Restart nginx
â Confirm success
â Create clean nginx config
â Test configuration
â Restart nginx
â Confirm success
8
Enable & Start Nginx
Bash
sudo nginx -t
sudo systemctl restart nginx
sudo systemctl enable nginx
9
Configure Firewall
Bash
sudo ufw allow 5000/tcp
sudo ufw status
đ Deployment Complete!
Test your frontend:Open in browser:
http://YOUR-FRONTEND-VM-IP:5000You should see: "Frontend is Working! đ"
Method 2: Build Locally & Deploy
⥠Faster Approach: Build on your local machine and transfer only the compiled artifacts to the VM. No Node.js needed on server!
1
Configure Environment (Local)
Navigate to your frontend project folder and edit .env:
ENV
VITE_API_URL=http://74.234.94.110:8000
VITE_ENVIRONMENT=production
â ī¸ Update with your backend IP!
2
Install Dependencies (Local)
Bash
npm install
3
Build Project (Local)
Bash
npm run build
â
This creates:
dist/public/ folder with production files
4
Transfer Artifacts to VM
From Windows PowerShell:
PowerShell
scp -r "E:\path\to\your-project\dist\public\*" user@frontend-vm-ip:"~/"
5
Deploy Artifacts on VM
SSH into your VM and run:
Bash
sudo rm -rf /var/www/html/*
cd ~
sudo mv * /var/www/html/
â ī¸ Caution: This removes existing files in
/var/www/html/
6
Configure Nginx
Run this complete configuration script:
Bash Script
sudo bash << 'EOF'
cat > /etc/nginx/sites-available/default << 'NGINX'
upstream backend_api {
server <insert_Here_Backend_VM_pip>:8000 fail_timeout=0;
keepalive 32;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
client_max_body_size 10M;
location / {
root /var/www/html;
try_files $uri $uri/ /index.html;
add_header Cache-Control "no-cache, no-store, must-revalidate" always;
add_header Pragma "no-cache" always;
add_header Expires "0" always;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
root /var/www/html;
expires 30d;
add_header Cache-Control "public, immutable";
try_files $uri =404;
}
location /api/ {
proxy_pass http://backend_api;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
proxy_connect_timeout 10s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
NGINX
nginx -t && systemctl restart nginx && echo "â
nginx fixed!"
EOF
7
Restart Nginx
Bash
sudo nginx -t
sudo systemctl restart nginx
sudo systemctl enable nginx
đ Deployment Complete!
Test your frontend:Open in browser:
http://YOUR-FRONTEND-VM-IP⨠Advantages of Method 2:
â Faster deployments (no build time on server)
â No Node.js needed on production server
â Smaller server footprint
â Better for CI/CD pipelines
đ Troubleshooting Guide
â Problem: 404 Not Found
Solution:
Bash
ls -la /var/www/html/
sudo nginx -t
sudo systemctl status nginx
Check if files exist and nginx is running properly.
â Problem: API Calls Failing
Checklist:
- Verify backend VM IP in nginx config
- Check if backend is running:
curl http://backend-ip:8000/health - Review nginx error logs:
sudo tail -f /var/log/nginx/error.log - Verify firewall rules allow port 8000
â Problem: Nginx Won't Start
Bash
sudo nginx -t
sudo journalctl -u nginx -n 50
Check for syntax errors in configuration files.
â Problem: Static Assets Not Loading
Verify file permissions:
Bash
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/html
đ§ Useful Debug Commands
sudo systemctl status nginx- Check nginx statussudo tail -f /var/log/nginx/access.log- Watch access logssudo tail -f /var/log/nginx/error.log- Watch error logscurl -I http://localhost- Test from VMnetstat -tlnp | grep nginx- Check nginx ports
â Quick Health Check Script
Bash
#!/bin/bash
echo "đ Checking Deployment Health..."
echo ""
echo "1. Nginx Status:"
sudo systemctl is-active nginx
echo ""
echo "2. Files in /var/www/html:"
ls -lh /var/www/html/ | wc -l
echo ""
echo "3. Nginx Config Test:"
sudo nginx -t
echo ""
echo "4. Listening Ports:"
sudo netstat -tlnp | grep nginx
echo ""
echo "5. Recent Errors:"
sudo tail -n 5 /var/log/nginx/error.log