How to Host a Static Website on a VPS with Nginx

Static websites — plain HTML, CSS, and JavaScript with no server-side processing — are the fastest, simplest, and most secure type of site to host. This guide covers serving one efficiently with Nginx.

Prerequisites

  • Nginx installed — see How to Install Nginx on Ubuntu & Debian
  • Your static site files (HTML/CSS/JS) ready to upload

Step 1 — Create the Site Directory

sudo mkdir -p /var/www/mysite/html
sudo chown -R $USER:$USER /var/www/mysite/html

Step 2 — Upload Your Site Files

rsync -avz ./dist/ deploy@YOUR_SERVER_IP:/var/www/mysite/html/

Step 3 — Create an Nginx Server Block

sudo nano /etc/nginx/sites-available/mysite
server {
    listen 80;
    listen [::]:80;
    server_name mysite.com www.mysite.com;

    root /var/www/mysite/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~* \.(jpg|jpeg|png|gif|css|js|woff2|svg)$ {
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }
}

Step 4 — Enable the Site

sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Step 5 — Add HTTPS

sudo certbot --nginx -d mysite.com -d www.mysite.com

Enabling Gzip Compression

gzip on;
gzip_types text/plain text/css application/javascript application/json image/svg+xml;
gzip_min_length 256;

Setting a Custom 404 Page

error_page 404 /404.html;
location = /404.html {
    root /var/www/mysite/html;
    internal;
}

Adding Security Headers

add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

Enabling HTTP/2

See How to Enable HTTP/2 and HTTP/3 on Nginx — particularly beneficial for static sites with many separate assets (images, CSS, JS files) loaded per page.

Common Errors

403 Forbidden — verify file ownership and that index.html actually exists in the specified root directory.

Changes to files don't appear — check for aggressive browser caching; hard-refresh, or verify your cache-busting strategy if using one (see How to Configure Browser Caching and Cache-Busting for Static Assets).

Best Practices

  • Enable both gzip compression and long-term caching headers for static assets
  • Always serve over HTTPS
  • Add basic security headers even for simple static sites

Continue Reading

Browse more articles in Static Site Hosting & Frontend Deployment.

  • static website hosting, nginx static site, html hosting, static site vps
  • 1 کاربر این را مفید یافتند
آیا این پاسخ به شما کمک کرد؟

مقالات مربوطه

How to Deploy a Next.js Application on a VPS

Next.js supports several deployment modes — fully static export, server-side rendering with...

How to Deploy a Static Site Built with Astro, Hugo, or Jekyll

Static site generators (Astro, Hugo, Jekyll) produce plain HTML/CSS/JS at build time —...

How to Optimize Images for Web Performance

Images are typically the largest contributor to page weight and load time. This guide covers...

How to Set Up a Jamstack Site with a Headless CMS Backend

The Jamstack architecture (JavaScript, APIs, Markup) combines a pre-built static frontend with a...

How to Configure Nginx for Single Page Applications (SPA Routing)

Single Page Applications (React, Vue, Angular) handle routing client-side in JavaScript —...