Deploying Static Sites with CDN Acceleration
Serve a static site or SPA with Nginx, then layer a CDN on top for fast, resilient global delivery.
Why static + CDN
A static site (HTML/CSS/JS plus images) does no server-side work, which makes it a perfect fit for caching and distribution. Host it on your VPS, put a CDN in front, and edge nodes close to each visitor can serve the content directly — cutting latency and taking load off your origin.
Serving static files with Nginx
On Ubuntu/Debian, install Nginx and prepare a document root:
sudo apt update
sudo apt install -y nginx
sudo mkdir -p /var/www/mysite
# copy your build output (the contents of dist/) into /var/www/mysite
A minimal site config (/etc/nginx/sites-available/mysite):
server {
listen 80;
server_name example.com;
root /var/www/mysite;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
The key for SPAs: tryfiles fallback
Client-side routers (Vue, React, and friends) have no file on disk for a deep link like /user/123. tryfiles $uri $uri/ /index.html; looks for a real file first and, when none exists, falls back to index.html so the router can take over — no more 404s on refresh.
Enable the site and reload:
sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
How a CDN works
- Edge caching: the CDN runs edge nodes worldwide and stores your static assets close to users.
- Origin pull: on a cache miss (or once content expires), the edge fetches once from your origin, then caches the copy for later requests.
Putting a CDN in front, step by step
- Add your domain in the CDN console and point its origin at your VPS's public IP or origin hostname.
- Update your DNS so the domain's CNAME points to the address the CDN hands you.
- Set the origin protocol and cache rules, and turn on HTTPS.
- Once it propagates, run curl -I https://example.com and check the response headers for the CDN's cache status.
Cache strategy and Cache-Control
Hit rate is driven by the headers your origin sends. Cache fingerprinted assets for a long time, but keep the entry index.html short-lived or uncached:
location ~* \.(?:css|js|woff2?|png|jpg|jpeg|svg|ico)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000, immutable";
}
location = /index.html {
add_header Cache-Control "no-cache";
}
immutable tells browsers the file will never change, so they skip revalidation; no-cache makes the entry HTML revalidate every time, so a new release goes live promptly.
Purging the cache
If the edge still holds stale files after a deploy, run a purge from the CDN console by URL or path; many CDNs also let you prefetch popular assets onto the edge. The sturdier habit is to put a content hash in filenames (e.g. app.a1b2c3.js) — a new name sidesteps the cache entirely.
Benefits of pairing a static site with a CDN
- Lower latency: served nearby, so the first paint lands faster.
- Lighter origin: most requests hit the edge, easing VPS bandwidth and load.
- Better burst tolerance: traffic spikes get absorbed by the edge nodes.
Summary
Serve your static site or SPA reliably with Nginx's tryfiles, then let a CDN handle edge caching and origin pull. Use Cache-Control to separate long-lived assets from the short-lived entry HTML, pair it with hashed filenames and cache purges, and you get a static deployment that's fast, cheap, and resilient.