Virteche
Guideschevron_rightServers

Servers · 8 min read · Updated

How to Host a Website on a VPS with Nginx and Let's Encrypt

A website on a VPS needs four things: a DNS record pointing your domain at the server, a web server to answer requests, a certificate for HTTPS, and a firewall that lets the web traffic in. On Ubuntu or Debian that is Nginx and Certbot, about ten minutes of work, and nothing to renew by hand afterwards. The commands below assume Ubuntu 24.04 or Debian 12 and a user with sudo.

1. Point Your Domain at the Server

At your DNS provider, create an A record for the domain (and one for www if you want it) with your server's IPv4 address from the dashboard. Then check it from your own computer — Certbot will fail until this answers with the right address:

dig +short example.com
dig +short www.example.com

2. Install Nginx and Open the Firewall

sudo apt update
sudo apt install -y nginx ufw
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'     # ports 80 and 443
sudo ufw enable

Allow OpenSSH before enabling the firewall, or you will lock yourself out. If that happens anyway, the browser VNC console still gets you in. If you turned on the firewall on your server's page in the dashboard, allow web (80, 443) there too. Opening your server's IP address in a browser should now show the Nginx welcome page.

3. Add Your Site

Make a folder for the files and a server block that serves it:

sudo mkdir -p /var/www/example.com
echo '<h1>It works</h1>' | sudo tee /var/www/example.com/index.html
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;
    index index.html;

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

Enable it, test the configuration, and reload:

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

4. Turn On HTTPS

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

Certbot proves you control the domain over port 80, fetches a free Let's Encrypt certificate, rewrites your server block to use it, and adds a redirect from HTTP to HTTPS. Renewal is automatic; confirm it with:

sudo certbot renew --dry-run
systemctl list-timers | grep certbot

5. Upload Your Files

From your own computer, rsync copies only what changed. Give your user ownership of the folder first so you do not need root to deploy:

# on the server
sudo chown -R $USER:$USER /var/www/example.com

# on your computer
rsync -av --delete ./site/ [email protected]:/var/www/example.com/

6. Or Put an App Behind Nginx

For a Node, Python or Go app listening on a local port, replace the location / block with a reverse proxy. Keep the app bound to 127.0.0.1 so the only way in is through Nginx:

location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Upgrade $http_upgrade;     # WebSockets
    proxy_set_header Connection $connection_upgrade;
}

$connection_upgrade asks for an upgrade only when the browser does. Define it once, in /etc/nginx/conf.d/connection-upgrade.conf:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

Run the app as a systemd service or in a container so it restarts on its own — the Docker guide covers the second option.

Before You Call It Done

Work through first steps on a new Linux server (SSH keys, no password logins, automatic security updates), and back the site and its database up somewhere other than the server itself — the Borg guide does it nightly.

Common Questions

  • Do I need a control panel like cPanel?

    No. For one or a handful of sites, Nginx plus Certbot is all a control panel would be doing for you, with nothing extra to update or pay for. A panel starts to earn its keep when you host many sites for other people.

  • Why does Certbot say the challenge failed?

    Almost always one of three things: the domain's A record does not point at this server yet (check with dig +short example.com), port 80 is closed in the firewall, or the server_name in the Nginx config does not match the domain you asked for.

  • Which plan do I need?

    A static site or a small app runs happily on the smallest VPS. Size up for the application behind Nginx, not for Nginx itself — a database and a Node, PHP or Python app are what use the memory.

  • Do I have to renew the certificate?

    No. The Certbot package installs a timer that renews certificates well before they expire and reloads Nginx. certbot renew --dry-run proves it will work.

KVM servers in Ashburn and Dallas, built automatically with the OS you choose.

See VPS plans

Keep Reading

All guides
Host a Website on a VPS with Nginx and HTTPS | Virteche