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.