6 minutes
Blazing Fast & Dirt Cheap: Nginx, Cloudflare, and a VPS

Building modern web applications with frameworks like React, Vue, or Angular is powerful, but hosting them can sometimes feel complex or costly. What if you could get global CDN speeds for your frontend and efficiently host your backend API, all for just a few bucks a month?
You absolutely can. By combining a lean VPS, the versatile Nginx web server, and Cloudflare’s incredible free tier, you can create a setup that embraces the best parts of the Jamstack architecture: serving your static frontend globally at light speed while efficiently handling dynamic API requests from a low-cost server.
Why This Stack is Perfect for Modern Web Apps:
- Cheap VPS ($3-5/month): Your affordable, controllable home base. Use it to serve the initial files and, more importantly, to run your backend API (Node.js, Python, Go, etc.) if you have one. Providers like Hetzner, Vultr, DigitalOcean offer plans that fit the bill.
- Nginx (Free, Fast, Flexible): It’s not just a static file server! Nginx excels at serving your built frontend assets (the static HTML, CSS, JS generated by your framework’s build process). Crucially, it’s also a fantastic reverse proxy, meaning it can intelligently route requests for
/api
(or similar paths) to your backend application running on the same VPS. - Cloudflare (The Free Performance Engine): This is the key to speed and savings.
- Global CDN: Serves your static frontend from datacenters worldwide. Users load your app’s interface almost instantly from a server near them.
- Caching: We’ll tell Cloudflare to aggressively cache your static frontend. This means most users won’t even hit your VPS for the interface files, dramatically reducing its load. Your server only needs to worry about dynamic API calls.
- Security: Provides essential protection against common web threats.
Let’s Set Up Your Modern Hosting Platform:
Step 1: Your Server’s Foundation (VPS + Nginx)
- Get a VPS: Sign up with a provider and get a basic Linux VPS (Ubuntu is common). Note its IP address.
- Connect via SSH: Use SSH to access your server’s command line.
- Install Nginx:
sudo apt update sudo apt install nginx -y
- Create a Directory for Your Frontend Build: Instead of a generic
html
folder, let’s use something more descriptive. This is where you’ll put the output of yournpm run build
or similar command (e.g., thebuild
ordist
folder).# Replace 'yourdomain.com' with your actual domain # You might choose /srv/ or /var/www/ based on preference sudo mkdir -p /var/www/yourdomain.com/frontend
- Upload Your Built Frontend: Copy the contents of your framework’s build output directory (e.g., everything inside
my-react-app/build/
) into the/var/www/yourdomain.com/frontend/
directory on your VPS usingscp
, SFTP (FileZilla),rsync
, or Git deployment. - Configure Nginx for Your Frontend: Create an Nginx configuration file:
Paste in this configuration, adjusting
sudo nano /etc/nginx/sites-available/yourdomain.com
yourdomain.com
and theroot
path if you chose differently:Save the file (server { listen 80; server_name yourdomain.com www.yourdomain.com; # Path to your built frontend files root /var/www/yourdomain.com/frontend; index index.html index.htm; location / { # Crucial for Single Page Applications (SPAs) like React/Vue/Angular: # Try serving the exact file requested ($uri), then try it as a directory ($uri/), # If neither exists, fall back to serving /index.html. # This lets your frontend framework handle routing. try_files $uri $uri/ /index.html; } # Basic security headers (optional but good practice) add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; add_header Referrer-Policy "strict-origin-when-cross-origin"; add_header Permissions-Policy "interest-cohort=()"; # Disable FLoC }
Ctrl+X
,Y
,Enter
). - Enable Site & Restart Nginx:
Your frontend app should now be accessible via your VPS IP address.
sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/ sudo rm /etc/nginx/sites-enabled/default # Remove default config if present sudo nginx -t # Test config sudo systemctl restart nginx # Apply changes
Step 2: Supercharge with Cloudflare
- Sign up & Add Domain: Create a free Cloudflare account and add your domain.
- Point DNS to VPS: In Cloudflare’s DNS settings, delete any conflicting ‘A’, ‘AAAA’, or ‘CNAME’ records for your root domain (
@
) andwww
. Add an ‘A’ record for@
pointing to your VPS IP Address, and a ‘CNAME’ record forwww
pointing to@
(or yourdomain.com). Ensure both have the Proxy status set to Orange (Proxied). - Update Nameservers: Go to your domain registrar and change the nameservers to the ones Cloudflare provides. (Allow time for this change to propagate).
- Configure SSL/TLS: In Cloudflare, set SSL/TLS mode to Full (Strict) for best security. (Consider installing a free Let’s Encrypt certificate on Nginx using
certbot
for full end-to-end encryption).
Step 3: Cache the Frontend Aggressively (Load Reduction!)
This is where you drastically reduce load on your VPS.
- Go to Rules -> Page Rules in Cloudflare.
- Click Create Page Rule.
- URL:
*yourdomain.com/*
(Applies to everything). - Settings:
- Cache Level: Cache Everything (Caches the HTML, CSS, JS of your frontend).
- Edge Cache TTL: Choose how long Cloudflare caches before checking your server (e.g.,
1 day
, or longer if your frontend rarely changes).
- Click Save and Deploy.
The Result: Visitors worldwide load your app’s interface from Cloudflare’s edge. Your VPS only gets hit when the cache expires or when API calls are made (see next step).
Critical Note on Deploying Frontend Updates: When you deploy a new version of your frontend code to the VPS, you must tell Cloudflare to clear its cache so users get the latest version. Go to Caching -> Configuration -> Purge Cache -> Purge Everything in Cloudflare.
Step 4 (Optional): Routing API Requests with Nginx
If your application has a backend API (e.g., Node.js/Express running on port 3001, Python/Flask on port 5000) on the same VPS, you can use Nginx to route requests to it.
- Edit Your Nginx Config:
sudo nano /etc/nginx/sites-available/yourdomain.com
- Add an API Location Block: Inside the
server { ... }
block, before the closing}
, add a newlocation
block. This example assumes your API runs onhttp://localhost:3001
and you want requests toyourdomain.com/api/...
to go to it:# ... other directives like root, index, existing location / ... # Route API requests location /api/ { # Forward requests to the backend application running locally on port 3001 proxy_pass http://localhost:3001/; # Standard proxy headers to pass along useful info to the backend 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; # Optional: Increase timeouts if your API calls might take longer # proxy_connect_timeout 60s; # proxy_send_timeout 60s; # proxy_read_timeout 60s; } # Make sure your main location block for the frontend is still present location / { try_files $uri $uri/ /index.html; }
- Important: The trailing slash in
proxy_pass http://localhost:3001/;
can be significant depending on your backend routing setup. Adjust as needed.
- Important: The trailing slash in
- Test and Restart Nginx:
sudo nginx -t sudo systemctl restart nginx
API Caching Consideration: Your “Cache Everything” rule might cache API responses if your API doesn’t send correct Cache-Control
headers (like Cache-Control: no-cache, no-store, must-revalidate
or Cache-Control: private
). Ensure your API sends appropriate headers for dynamic content to prevent Cloudflare from caching it incorrectly. Alternatively, create a second Page Rule specifically for *yourdomain.com/api/*
with the setting Cache Level: Bypass
.
The Jamstack Payoff: Cost & Performance
- Cost: Still around $4 - $6 per month (VPS + Domain).
- Performance: Your static frontend (React, Vue, etc.) loads incredibly fast from the global Cloudflare CDN. Your cheap VPS is freed up to solely handle the (often less frequent) dynamic API requests. This is a highly efficient and scalable architecture.
Conclusion: Modern Hosting, Simplified
By combining a low-cost VPS, the efficiency of Nginx (for both static files and API routing), and the powerful caching of Cloudflare, you achieve a high-performance hosting setup for modern web applications without the high cost. It’s a practical, affordable way to leverage Jamstack principles: serve static fast, handle dynamic smart. Go build something awesome!