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.