Coding

Deploy a static website with Nginx and free HTTPS

By Ali Ghafori · 3 min read

A static website — plain HTML, CSS and JavaScript files — is the fastest, cheapest and most secure kind of site you can run. There's no database to hack and nothing to update every week. This guide shows how to put one online on your own Linux server with Nginx and a free HTTPS certificate. It's exactly how this site is hosted.

What you need

1. Install Nginx

sudo apt update
sudo apt install nginx
sudo systemctl enable --now nginx

Open http://your-server-ip in a browser. If you see the "Welcome to nginx" page, the web server is running. If not, check that ports 80 and 443 are open in your firewall:

sudo ufw allow 'Nginx Full'

2. Upload your site

Create a folder for the site and copy your files into it. From your own computer you can use scp or rsync:

sudo mkdir -p /var/www/example.com
rsync -avz ./site/ root@your-server-ip:/var/www/example.com/

3. Create an Nginx server block

Create /etc/nginx/sites-available/example.com:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    root /var/www/example.com;
    index index.html;

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

try_files tells Nginx to serve the exact file if it exists, then a folder's index.html, and otherwise return a 404. Enable the site and reload:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Always run nginx -t before reloading. It checks the configuration for errors, so a typo never takes your site offline.

4. Add free HTTPS with Let's Encrypt

Certbot requests a certificate and configures Nginx for you:

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com

Choose the option to redirect HTTP to HTTPS. Certificates last 90 days, and Certbot installs a timer that renews them automatically. You can test renewal with:

sudo certbot renew --dry-run

5. Make it fast

A few lines inside the server block make a noticeable difference:

gzip on;
gzip_types text/css application/javascript image/svg+xml;

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

Compression shrinks text files, and caching headers let returning visitors load images and stylesheets from their own browser instead of downloading them again. Also compress your images (WebP is usually much smaller than PNG or JPEG) — they're almost always the heaviest part of a page.

6. Updating the site

To publish changes, just upload the new files again with the same rsync command. There's no restart needed: Nginx serves the new files immediately.

Common problems

That's it — a fast, secure website with automatic HTTPS, for the cost of a small server.

← Back to all articles