React is the world’s most popular JavaScript library for building modern, interactive Single Page Applications (SPAs). When deploying a React application to a production Ubuntu Linux Virtual Private Server (VPS), the application is compiled into optimized static HTML, CSS, and JavaScript bundles. Serving these static assets with Nginx delivers blazingly fast load times, minimal CPU/memory utilization, and rock-solid scalability.
In this comprehensive, beginner-friendly guide, we will walk you through deploying a production-ready React application (built with Vite or Create React App) on Ubuntu 26.04 LTS, Ubuntu 24.04 LTS, Ubuntu 22.04 LTS, or Ubuntu 20.04 LTS using Nginx. We also cover crucial production features including React Router SPA fallback configuration (preventing 404 errors on page refresh), Gzip compression, static asset caching, and backend API reverse proxying.
Prerequisites
- An active Linux Virtual Private Server (VPS) running Ubuntu (20.04, 22.04, 24.04, or 26.04 LTS).
- SSH access with
sudoor root privileges. - Nginx installed and configured on your server (see How to Set Up Nginx on Ubuntu Server).
- A registered domain pointing its DNS A Record to your VPS IP address (refer to How to Point Your Domain to a VPS IP Address).
- Let’s Encrypt SSL installed for HTTPS security (see How to Install Let's Encrypt SSL on Ubuntu Server).
- Note for DirectAdmin shared hosting users: If you are using a DirectAdmin control panel rather than a standalone Ubuntu VPS, see our dedicated guide on How to Deploy a React Website in DirectAdmin.
Step-by-Step Guide: How to Deploy React on Ubuntu Server
Step 1: Build the Production React Application
Before deploying to your server, compile your React project into an optimized production build on your local machine (or directly on your VPS):
- For Vite-based React projects:
npm run buildThis generates an optimized static folder named
dist/. - For Create React App (CRA) projects:
npm run buildThis generates an optimized static folder named
build/.
Step 2: (Optional) Install Node.js on Ubuntu Server
If you prefer to build or maintain your React code directly on your Ubuntu VPS, install the latest LTS version of Node.js (Node 20.x):
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
node -v && npm -v
Step 3: Transfer React Production Files to Your VPS
- Create the web directory for your domain on the VPS:
sudo mkdir -p /var/www/domain.com/html - Upload your compiled build files (the contents of
dist/orbuild/) to the server usingscp, SFTP, or Git:# Example uploading via SCP from your local machine: scp -r dist/* username@YOUR_SERVER_IP:/var/www/domain.com/html/ - Set appropriate permissions and ownership for the web server user (
www-data):sudo chown -R www-data:www-data /var/www/domain.com/html sudo chmod -R 755 /var/www/domain.com/html
Step 4: Configure Nginx Server Block with React Router Support
Single Page Applications (SPAs) utilize client-side routing (e.g. React Router). When a user navigates directly to a subpage like domain.com/dashboard or refreshes their browser, Nginx must serve index.html so that React can handle the route. Without the try_files directive, Nginx will return a 404 Not Found error.
- Create or edit your Nginx server block configuration:
sudo nano /etc/nginx/sites-available/domain.com - Paste the following production-optimized configuration:
server { listen 80; listen [::]:80; server_name domain.com www.domain.com; root /var/www/domain.com/html; index index.html index.htm; # Enable Gzip Compression for fast delivery gzip on; gzip_vary on; gzip_min_length 1024; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml application/javascript application/json; # 1. Essential: React Router Single Page Application Fallback location / { try_files $uri $uri/ /index.html; } # 2. Browser Caching for Static JS, CSS, and Images location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, no-transform"; } # 3. (Optional) Reverse Proxy for Backend API (Node.js, Python, Laravel) location /api/ { proxy_pass http://127.0.0.1:5000/; 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; } # Logging access_log /var/log/nginx/domain.com.access.log; error_log /var/log/nginx/domain.com.error.log; }Save and exit by pressing
CTRL + O,ENTER, andCTRL + X.
Step 5: Enable Configuration and Reload Nginx
- Create a symbolic link in
sites-enabled(if not already present):sudo ln -s /etc/nginx/sites-available/domain.com /etc/nginx/sites-enabled/ - Test your Nginx configuration syntax:
sudo nginx -t - Reload Nginx to apply the changes:
sudo systemctl reload nginx
Step 6: Secure Your React App with Free Let’s Encrypt SSL
Run Certbot to automatically enable HTTPS encryption on your domain:
sudo certbot --nginx -d domain.com -d www.domain.com
Visit https://domain.com in your browser to experience your high-speed, SSL-secured React application!
Frequently Asked Questions & Troubleshooting
Q: Why does refreshing a subpage (e.g. /about or /dashboard) give a 404 error?
A: Nginx looks for a physical directory or file named /about on the filesystem. Since React handles routing inside JavaScript, you must include try_files $uri $uri/ /index.html; in your Nginx configuration to redirect all unmatched requests back to React’s entry point.
Q: How do I manage environment variables for production?
A: In Vite, create a .env.production file containing VITE_API_BASE_URL=https://domain.com/api before running npm run build. In Create React App, prefix variables with REACT_APP_.
Q: How do I update my React app after making changes?
A: Run npm run build locally, upload the new files into /var/www/domain.com/html, and your updates will be live instantly with zero downtime.
Need Further Assistance?
If you need assistance deploying React applications, setting up reverse proxies for Node.js/Python backends, or configuring SSL on your Ubuntu VPS, our technical team is available 24/7. Feel free to submit a support ticket for prompt, expert help.