Assumes Ubuntu or Debian, a server with a public IPv4 address, and a domain you control.
1. Point the domain at the server
At your DNS provider, an A record for example.com to your server's IPv4
address, and another for www. Then check it from your own machine:
dig +short example.com
Wait until that returns your server's address. A certificate cannot be issued before it does.
2. Open ports 80 and 443
On the server's Networking tab, add inbound allow rules for TCP 80 and TCP
443 from 0.0.0.0/0. See The cloud firewall.
3. Install nginx
sudo apt update
sudo apt install -y nginx
Visit http://your-ip/ and you should get the nginx welcome page. If you do not,
the firewall rule is the first thing to check.
4. Serve your site
sudo mkdir -p /var/www/example.com
sudo chown -R "$USER":"$USER" /var/www/example.com
echo '<h1>It works</h1>' > /var/www/example.com/index.html
sudo tee /etc/nginx/sites-available/example.com >/dev/null <<'EOF'
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;
}
}
EOF
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx
nginx -t before every reload. It catches the typo while the old config is still
running.
5. Get a certificate
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
Certbot edits the nginx config for you, adds the redirect from HTTP, and installs a systemd timer that renews automatically. Confirm the timer:
systemctl list-timers | grep certbot
sudo certbot renew --dry-run
6. Check the result
curl -I https://example.com
Look for a successful response. Certificate lifetimes can change, so rely on
Certbot's remaining-lifetime check rather than a fixed renewal day. Keep its
timer enabled and run certbot renew --dry-run after changing DNS, firewall, or
web-server configuration.
Common failures
| Symptom | Cause |
|---|---|
| Connection times out | Port 80 or 443 not open in the cloud firewall |
| Connection refused | Nginx is not running: systemctl status nginx |
| Certbot cannot validate | DNS not pointing here yet, or port 80 closed |
| 502 Bad Gateway | Nginx is up but your application behind it is not |
| Works on IP, not on domain | server_name does not match, or DNS is wrong |