NewHalo Edge 3 is here: HTTP/3 everywhere and 42 edge locations.Learn more
Docs / Web servers

Host a static website

Web servers6 min readUbuntu 24.04 LTS

Upload a folder of HTML, CSS and images to your VPS and serve it with nginx, a fast and widely used web server. By the end, your site will answer at http://example.com.

Before you begin

  • A VPS running Ubuntu 24.04 LTS with a public IP address, for example 203.0.113.10.
  • SSH access as root or as a user with sudo rights. This guide uses a sudo user named alex.
  • A domain name whose DNS A record points at your VPS IP. If your domain is managed in Lantern DNS, you can add the record in the DNS editor. DNS changes can take a while to spread.
  • Your site files on your computer, in a folder with an index.html file at the top level.

Step 1: Update the server and install nginx

Refresh the list of available packages, install any pending updates, and then install nginx. The -y flag answers "yes" to prompts automatically.

sudo apt update
sudo apt upgrade -y
sudo apt install -y nginx

When nginx installs, it starts itself and serves a "Welcome to nginx" page. You will replace that page with your own in later steps.

Step 2: Allow web traffic through the firewall

Ubuntu includes ufw, a simple firewall. Allow SSH first so you cannot lock yourself out, then allow the nginx web profile (ports 80 and 443), and turn the firewall on.

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Nginx Full                 ALLOW       Anywhere
Careful: Always allow OpenSSH before running ufw enable. If you skip it, the firewall can block your own SSH connection.

Step 3: Create a folder for your site

Create the folder that will hold the site, then give your login account ownership of it so you can upload files without sudo. The -p flag creates any missing parent folders.

sudo mkdir -p /var/www/example.com/html
sudo chown -R $USER:$USER /var/www/example.com

Step 4: Upload your files

Run this command on your own computer, not on the server. scp copies files over SSH. Replace alex and the IP address with your own values.

scp -r ./my-site/* alex@203.0.113.10:/var/www/example.com/html/

Back on the server, confirm the files arrived:

ls /var/www/example.com/html
about.html  css  images  index.html
Tip: For larger sites, rsync -av ./my-site/ alex@203.0.113.10:/var/www/example.com/html/ is faster on repeat uploads because it only sends changed files.

Step 5: Create an nginx server block

nginx uses "server blocks" to decide what to serve for each domain name. Create a new configuration file for your domain. Inside the editor, paste the contents shown below.

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

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

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

The root line tells nginx where your files live. try_files serves the requested file, or a folder's index file, or a 404 if neither exists.

Next, enable the site, disable the default welcome site, check the configuration for mistakes, and reload nginx:

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

The ln -s command enables your site by creating a link. nginx -t tests the configuration without applying it, and reload applies changes without dropping active connections.

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Step 6: Test the site

Ask the server for the response headers of your home page. -I fetches headers only, which is a quick way to confirm the status code.

curl -I http://example.com
HTTP/1.1 200 OK
Server: nginx/1.24.0 (Ubuntu)
Content-Type: text/html
Content-Length: 512

Then open http://example.com in a browser. You should see your home page.

Troubleshooting

  • You still see the "Welcome to nginx" page. Check that the default site is gone with ls -l /etc/nginx/sites-enabled, then run sudo systemctl reload nginx. Your browser may also be caching the old page, so try a private window.
  • 403 Forbidden. nginx cannot read the files, or there is no index.html. Check the path with ls -l /var/www/example.com/html, and read the error log with sudo tail -n 20 /var/log/nginx/error.log.
  • The domain does not load but the IP does. DNS has not updated yet. Check it with dig +short example.com, which should print 203.0.113.10.
  • nginx -t reports an error. The message includes a file name and line number. The most common cause is a missing semicolon or an unmatched brace.

Next steps

Your site is live over plain HTTP, which means visitors' traffic is not encrypted. Add a free TLS certificate next, using certbot. Then read Create custom error pages to make missing-page responses match your site.

Something not working? Chat or email our support team and we will help you get unstuck.

Contact support