Disclosure: we may earn a commission or referral reward from CloudCone, Contabo, DigitalOcean (account credit, not cash), Hostwinds, InterServer, RackNerd, VPSDime and Vultr if you sign up through our links. It does not change the price you pay. Every other provider pays us nothing. Prices in this guide are as of the date shown and may have changed; see the comparison pages for the latest checked prices.

Guides · BLOG

How to add Let's Encrypt SSL to any VPS in 2026

Some prices quoted in this guide are out of date. It is being rebuilt on our price index; for current prices use the comparison pages, which show when each price was checked.

Let's Encrypt gives you a free, valid SSL certificate for any domain you own. Setup takes 5 minutes with Certbot; auto-renewal is automatic. Every modern browser expects HTTPS. This guide is the complete walkthrough.

Prerequisites

  • A VPS with a public IP.
  • A domain name whose A record points at your VPS.
  • Port 80 and 443 open in your VPS firewall (ufw allow 80 && ufw allow 443).
  • Nginx or Apache already installed and serving something on port 80.

The 5-minute path (Nginx)

```bash

apt update

apt install certbot python3-certbot-nginx

Issue and configure the cert

certbot --nginx -d yourdomain.com -d www.yourdomain.com

```

Certbot walks you through:

  • Your email (for renewal reminders and account recovery).
  • Terms of Service acceptance.
  • Whether to redirect all HTTP traffic to HTTPS (say yes).

Done. Your site is now on HTTPS with a valid Let's Encrypt cert. Renewal is automatic.

For Apache

```bash

apt install certbot python3-certbot-apache

certbot --apache -d yourdomain.com -d www.yourdomain.com

```

Same flow. Certbot edits your Apache config.

For non-Nginx, non-Apache servers

Use standalone mode:

```bash

apt install certbot

Stop your server temporarily

systemctl stop your-web-server

Issue the cert

certbot certonly --standalone -d yourdomain.com

Certs are placed at:

/etc/letsencrypt/live/yourdomain.com/fullchain.pem

/etc/letsencrypt/live/yourdomain.com/privkey.pem

Configure your server to use them and restart

systemctl start your-web-server

```

Auto-renewal

Certbot installs a systemd timer (or cron entry on older systems) that runs certbot renew twice daily. Certs are valid for 90 days; renewal happens 30 days before expiry.

Verify:

```bash

certbot renew --dry-run

```

Should output "Congratulations, all simulated renewals succeeded."

Check the timer:

```bash

systemctl list-timers | grep certbot

```

Wildcard certificates

For *.yourdomain.com (covers all subdomains), you need DNS-01 challenge — which requires your DNS provider's API. Cloudflare, Route 53, DigitalOcean DNS all supported.

Cloudflare example:

```bash

apt install python3-certbot-dns-cloudflare

Create /root/.cloudflare.ini with:

dns_cloudflare_email = [email protected]

dns_cloudflare_api_key = your-global-api-key

chmod 600 /root/.cloudflare.ini

certbot certonly --dns-cloudflare \

--dns-cloudflare-credentials /root/.cloudflare.ini \

-d "*.yourdomain.com" -d "yourdomain.com"

```

Common errors and fixes

"Failed authorization procedure. yourdomain.com (http-01): urn:ietf:params:acme:error:connection"

  • Your firewall is blocking port 80 from Let's Encrypt's validation servers.
  • Fix: ufw allow 80.

"NXDOMAIN looking up A for yourdomain.com"

  • Your DNS A record isn't pointing at your VPS yet.
  • Fix: verify DNS with dig yourdomain.com. Wait for propagation.

"Cannot find working ACME server"

  • Rate limit hit (too many certs issued for this domain recently).
  • Fix: wait an hour, use --staging flag for testing, or use a different subdomain.

"Some challenges have failed."

  • Usually a DNS issue or Nginx not serving .well-known/acme-challenge/.
  • Fix: verify Nginx config passes nginx -t and reloads.

"An unexpected error occurred: The client lacks sufficient authorization"

  • Rare; usually indicates account issue with Let's Encrypt.
  • Fix: certbot register --update-registration or contact Let's Encrypt support.

Rate limits

Let's Encrypt has real rate limits:

  • 50 certificates per registered domain per week.
  • 5 duplicate certificates per week.
  • 300 New Orders per account per 3 hours.

Real production sites rarely hit these. If you're testing certbot config, use --staging flag to test against a rate-limit-free staging server.

Renewal failure alerting

If auto-renewal breaks and you don't notice for 60 days, your cert expires. Prevention:

Option 1: Certbot's built-in email. You entered an email during setup. Let's Encrypt sends expiry warnings 20 days before.

Option 2: Monitoring script. Cron this daily:

```bash

#!/bin/bash

EXPIRY=$(echo | openssl s_client -servername yourdomain.com -connect yourdomain.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f 2)

EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s)

NOW_EPOCH=$(date +%s)

DAYS_LEFT=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))

if [ "$DAYS_LEFT" -lt 20 ]; then

echo "SSL cert for yourdomain.com expires in $DAYS_LEFT days" | mail -s "SSL alert" [email protected]

fi

```

Option 3: External monitoring. UptimeRobot's paid tier includes SSL monitoring.

Why Let's Encrypt vs paid CA?

  • Trust: browsers trust Let's Encrypt the same as any paid CA.
  • Validation: Domain validation only (no OV or EV). If you need an "Extended Validation" cert (the green company name in the URL bar), you need a paid CA — but browsers largely stopped displaying EV differently in 2019+.
  • Wildcard: free with Let's Encrypt via DNS-01 challenge.
  • Cost: $0.

For 99% of sites, Let's Encrypt is exactly the right answer.

Cloudflare's SSL vs Let's Encrypt on the origin

If you use Cloudflare in front of your VPS:

  • Cloudflare's edge SSL is free.
  • Your VPS still needs a cert for origin traffic (Cloudflare → your VPS).
  • Two options: Let's Encrypt on origin (recommended), or Cloudflare Origin CA (long-lived cert only trusted by Cloudflare).

Origin CA is fine if you'll always be behind Cloudflare. Let's Encrypt is more flexible.

Related guides