Creating a free SSL certificate with Let's Encrypt and Certbot
Install Certbot, get a certificate for Nginx or Apache, handle wildcards and make sure automatic renewal really works.
Reading time: 3 min Updated on 26 October 2026
Let's Encrypt issues free certificates trusted by every browser. Certbot is the most widely used client for obtaining them and renewing them automatically. This guide covers a Linux server running Nginx or Apache. If your host offers a "Free SSL" or "Let's Encrypt" button, use that instead: it handles everything for you.
Prerequisites
- A domain name whose DNS records (A and/or AAAA) point to your server.
- Port 80 reachable from the Internet: Let's Encrypt checks that you control the domain through an HTTP request.
sudoaccess to the server.
1. Install Certbot
The method recommended by the EFF uses snap:
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
On Debian or Ubuntu, the distribution package works too:
sudo apt install certbot python3-certbot-nginx # or python3-certbot-apache
2. Get the certificate
With Nginx or Apache (the easiest way)
Certbot gets the certificate and updates the server configuration:
sudo certbot --nginx -d example.com -d www.example.com
# or
sudo certbot --apache -d example.com -d www.example.com
List every name that needs to be covered, each with its own -d. Certbot then offers to redirect HTTP to HTTPS: accept.
Without touching the configuration (webroot)
If you'd rather manage the configuration yourself, or you use a different web server:
sudo certbot certonly --webroot -w /var/www/example -d example.com -d www.example.com
The files are created in /etc/letsencrypt/live/example.com/:
fullchain.pem: the certificate and the intermediates. This is the one to configure on the server.privkey.pem: the private key.
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
Using cert.pem instead of fullchain.pem is the most common mistake: the site works in Chrome, but not in apps or with curl.
Wildcard certificate (*.example.com)
A wildcard requires DNS validation: a TXT record to create at every renewal. To automate it, use your provider's DNS plugin (Cloudflare, OVHcloud, Gandi, Route 53…):
sudo certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
-d example.com -d '*.example.com'
Avoid --manual in production: the certificate can't be renewed automatically.
3. Check automatic renewal
Let's Encrypt certificates last 90 days. Certbot installs a scheduled task that attempts renewal twice a day. It only actually replaces the certificate about 30 days before expiry.
sudo certbot renew --dry-run # full simulation
systemctl list-timers | grep certbot
sudo certbot certificates # current expiration dates
To make the server pick up the new certificate, add a deploy hook. It only runs after a successful renewal:
sudo sh -c 'printf "#!/bin/sh\nsystemctl reload nginx\n" > /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh'
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
4. Pitfalls that make renewal fail
- Port 80 closed later on: firewall, cloud security rule, or a redirect that blocks
/.well-known/acme-challenge/. - DNS changed: the domain now points to a CDN or another server.
- Server migration: the certificates were copied, but not Certbot or its scheduled task.
- Let's Encrypt rate limits: too many requests for the same domain in a short time. For testing, use
--test-cert, which goes through the staging environment with much higher limits. - Server never reloaded: the certificate is renewed on disk but not served to visitors.
5. What's changing at Let's Encrypt
- No more expiration emails since June 4, 2025. Let's Encrypt no longer warns you when a certificate is about to expire (details here).
- Shorter lifetimes: 64 days starting February 2027, then 45 days in February 2028 for the default profile. A failed renewal will leave you less and less time to react.
That's exactly what SSL Expiration Reminder covers: add your domains, and if a certificate hasn't been renewed in time, you get an alert by email, Slack or Telegram before your visitors land on an error page. Our renewal assistant also generates the right Certbot commands for your server.