Installing Free SSL with Let's Encrypt on DigitalOcean 2026 — Complete Guide
A practical guide to installing free SSL certificates with Let's Encrypt and Certbot on a DigitalOcean Droplet, covering issuance, auto-renewal, and troubleshooting.
HTTPS encryption has become the baseline standard for modern websites. Whether for SEO, credibility, or browser warnings that appear instantly if SSL is missing, it's no longer optional. Let's Encrypt is a Certificate Authority that issues SSL certificates for free and automatically, making it ideal for Droplets on DigitalOcean that require manual setup via Certbot. This guide walks you through the entire process: installation, certificate issuance, auto-renewal configuration, and troubleshooting common problems.
Contents
What is Let's Encrypt? Is It Really Free?
Let's Encrypt is a non-profit Certificate Authority (CA) operated by the Internet Security Research Group (ISRG), founded to push the entire internet toward HTTPS by default. It's backed by major organizations including Mozilla, EFF (Electronic Frontier Foundation), Cisco, Google Chrome, and numerous hosting providers. Its greatest strength is that SSL/TLS certificates issued by Let's Encrypt are 100% free—no hidden charges, no credit card required, and no limits on the number of domains you can use (subject to rate limiting to prevent abuse). A common question is: "Is it really free? Why?" The answer is that Let's Encrypt relies on full automation via the ACME protocol (Automatic Certificate Management Environment), dramatically reducing operational costs compared to traditional CAs that require staff to manually review documents. Certificates issued are Domain Validation (DV) only, meaning verification that you own the domain—not Extended Validation (EV) or Organization Validation (OV), which require company documents to display the business name in the browser's address bar. This makes them unsuitable for banks or organizations needing to display company identity, but perfectly adequate for typical websites, blogs, small-to-medium e-commerce shops, or API endpoints. One critical limitation to know: certificates expire after just 90 days—much shorter than typical purchased certificates (often 1+ years). This short lifespan is intentional: Let's Encrypt enforces automatic renewal to reduce risk from compromised private keys remaining in use for extended periods. With proper auto-renewal configuration from the start, system administrators barely need to think about it again. For DigitalOcean users, there are multiple ways to enable HTTPS depending on your architecture. Running a web server directly on a Droplet (self-managed) requires installing Certbot as this guide explains. App Platform handles SSL certificate issuance and renewal automatically the moment you bind a custom domain. Using a Load Balancer in front of multiple Droplets? DigitalOcean's Load Balancer has a built-in feature to automatically bind Let's Encrypt certificates via the Control Panel—no need to manage Certbot on each Droplet. This guide focuses on Droplet-based installation with Certbot, the most widely used and flexible approach.
- Let's Encrypt issues certificates completely free with no hidden costs
- Supports Domain Validation (DV) only—not EV/OV
- Certificate lifespan is just 90 days; auto-renewal is essential
- DigitalOcean offers three approaches: Droplet+Certbot, App Platform auto SSL, Load Balancer auto Let's Encrypt
Installing Certbot on Ubuntu/Debian
Certbot is the official client tool developed by EFF to communicate with Let's Encrypt automatically via the ACME protocol. It supports installation on Ubuntu and Debian through two main methods: apt package manager and snap. The Certbot team now officially recommends snap because it always provides the latest version with automatic updates.
The apt method (simpler, ideal for Droplets prioritizing simplicity) starts with updating your package list: sudo apt update. Then install Certbot along with the plugin for your web server. For Nginx, run sudo apt install certbot python3-certbot-nginx; for Apache, use sudo apt install certbot python3-certbot-apache. These plugins automatically modify your web server's configuration after successful certificate issuance, eliminating manual config editing.
Alternatively, install via snap—the method recommended first by Certbot's official documentation (certbot.eff.org). Ubuntu includes snapd by default. Run sudo snap install --classic certbot to install, then create a symlink to make the certbot command available system-wide: sudo ln -s /snap/bin/certbot /usr/bin/certbot.
Before issuing certificates, verify that your Droplet opens ports 80 (HTTP) and 443 (HTTPS) to incoming traffic. Let's Encrypt needs to reach your web server on port 80 to verify domain ownership (HTTP-01 challenge). If using ufw on Ubuntu, open them easily with sudo ufw allow 'Nginx Full' for Nginx or sudo ufw allow 'Apache Full' for Apache, which opens both ports together. If using DigitalOcean's Cloud Firewall (a free feature with no extra cost), add Inbound rules in the Control Panel to permit TCP ports 80 and 443 from Anywhere; otherwise, even if ufw is open, certificate requests will timeout due to Cloud Firewall blocking at the network layer. Test successful installation with certbot --version.
- apt:
sudo apt install certbot python3-certbot-nginx(or python3-certbot-apache) - snap (recommended by Certbot team):
sudo snap install --classic certbot - Open ports 80/443 in both ufw and DigitalOcean Cloud Firewall (free)
Issuing Certificates for Nginx/Apache
With Certbot and its plugin installed, issuing a certificate is a single command—Certbot handles everything automatically: domain verification, certificate request, and web server configuration updates.
For Nginx, run sudo certbot --nginx -d example.com -d www.example.com. You can specify multiple domains or subdomains by repeating the -d flag, perfect if you want both apex and www to share a single SAN certificate. For Apache, use the same command but with --apache: sudo certbot --apache -d example.com -d www.example.com.
On first run, Certbot prompts interactively for additional information: an email address for expiration and security alerts, agreement to Let's Encrypt's Terms of Service, and whether to automatically redirect HTTP traffic to HTTPS (highly recommended to force users to browse over HTTPS). After answering, Certbot automatically modifies Nginx or Apache's config, adding an HTTPS server block pointing to certificate files stored in /etc/letsencrypt/live/example.com/.
If you prefer Certbot not to modify your web server configuration—perhaps you use an unsupported server or have a complex existing setup—use certonly mode instead: sudo certbot certonly --nginx -d example.com. This issues the certificate without touching your config. Alternatively, sudo certbot certonly --standalone -d example.com temporarily starts its own web server on port 80 for verification, useful if no web server is running or you need certificates for non-web services like mail servers or custom applications.
After successful issuance, verify by visiting https://example.com in your browser—you should see a padlock icon. Or check all certificates on the Droplet with sudo certbot certificates to view expiration dates.
- Nginx:
sudo certbot --nginx -d example.com -d www.example.com - Apache:
sudo certbot --apache -d example.com - Use
certonly --standalonemode for non-web services
Setting Up Auto-Renewal for Certificates
Since Let's Encrypt certificates expire in just 90 days, auto-renewal setup is as crucial as initial issuance. The good news: current versions installed via apt or snap automatically set up a scheduled task—no manual configuration needed.
With snap installations, systemd automatically creates a timer. Check its status with systemctl status certbot.timer, which typically runs twice daily and renews only certificates expiring within 30 days (skipping others to avoid wasting rate limit quota). With apt installations on some distros, a cron job at /etc/cron.d/certbot handles this; inspect it with cat /etc/cron.d/certbot.
Always test renewal immediately after setup without waiting for actual expiration using sudo certbot renew --dry-run. This simulates the entire renewal process without contacting Let's Encrypt (preserving rate limit quota). If it completes error-free, your auto-renewal is ready.
A commonly overlooked detail: after renewal completes, your web server must reload the new certificate from disk—otherwise, the running process keeps using the old one in memory until restart. Certbot solves this via post-renewal hooks. Add a deploy hook to reload your web server gracefully: sudo certbot renew --deploy-hook "systemctl reload nginx". This signals Nginx to reload without dropping existing connections (different from restart, which cuts all connections).
For fine-grained schedule control, manually add a cron job like 0 0,12 * * * root certbot renew --quiet --post-hook "systemctl reload nginx" to run at midnight and noon daily. However, this is usually unnecessary since Certbot already handles it automatically. Periodically check renewal logs at /var/log/letsencrypt/letsencrypt.log for peace of mind.
- Certbot sets up auto-renewal automatically (systemd timer or cron) immediately after installation
- Test with
sudo certbot renew --dry-runwithout affecting rate limits - Auto-renewal only processes certificates expiring within 30 days
- Use
--deploy-hook "systemctl reload nginx"to gracefully reload the web server - Periodically check logs at
/var/log/letsencrypt/letsencrypt.log
Troubleshooting Common Issues
From multiple reviews, despite Certbot's user-friendly design, DigitalOcean users encounter recurring problems. The most common: 'Failed authorization procedure' or timeout during certificate issuance, typically caused by port 80 being blocked—either by ufw on the Droplet itself or by DigitalOcean's Cloud Firewall at the network layer. Check both layers because opening ufw alone isn't enough if Cloud Firewall blocks upstream. Quick test: curl -I http://example.com from outside DigitalOcean to verify port 80 is reachable before running certbot.
Second issue: DNS hasn't propagated yet or A records don't point to your Droplet's IP. Let's Encrypt must reach your domain over the internet to verify ownership. If DNS still points to old hosting or hasn't updated, certification fails immediately. Verify with dig example.com +short or nslookup example.com that the result matches your Droplet's IP before attempting certbot.
Third: hitting Let's Encrypt's rate limits—50 certificates per primary domain per week, and 5 duplicate certificates per week. This happens from repeatedly running certbot while debugging. Prevention: always use --dry-run or --staging during testing. Staging points to Let's Encrypt's test environment with relaxed limits and produces browsers-untrusted certificates (for testing only): sudo certbot certonly --staging -d example.com.
Other issues include private key permission errors after manually copying certificates between Droplets—don't do this. The /etc/letsencrypt/ folder contains complex symlink structures; instead, issue new certificates on the destination Droplet. Finally, mixed-content errors after enabling HTTPS—some assets (images, scripts, CSS) still hardcoded as http:// in HTML. Fix by using relative paths or switching to https:// throughout.
- Port 80 blocked by ufw or DigitalOcean Cloud Firewall—check both layers
- DNS hasn't propagated to your Droplet IP—verify with
dig example.com +short - Hit rate limit of 50 certs/week—use
--stagingduring testing - Don't copy
/etc/letsencrypt/between Droplets directly
When to Use This Feature (Real Use Cases)
Installing SSL via Certbot on a Droplet suits many scenarios but isn't always the right choice in DigitalOcean's ecosystem. Understanding when to choose which approach matters.
First scenario: a website or application running on a single Droplet with Nginx or Apache—WordPress, personal blog, small-to-medium API backend. Here, Certbot is the most straightforward choice: install once, auto-renew forever, zero additional DigitalOcean costs.
Second: multiple Droplets behind DigitalOcean's Load Balancer. No need to install Certbot on every Droplet. DigitalOcean Load Balancer (starting at $12/month) integrates Let's Encrypt automatically through the Control Panel—renewal happens at the Load Balancer level, reducing complexity managing certificates across many servers. Ideal for horizontal scaling architectures.
Third: needing a wildcard certificate covering all subdomains like *.example.com simultaneously. Standard HTTP-01 challenges can't do this; use DNS-01 via the certbot-dns-digitalocean plugin. This connects to DigitalOcean's API with a Personal Access Token, automatically creating DNS TXT records for verification without opening port 80. Perfect for teams managing many subdomains and wanting centralized certificate management.
Conversely, if using DigitalOcean's App Platform instead of managing Droplets directly, barely touch Certbot—the platform automatically issues and renews certificates the instant you bind a custom domain. Ideal for teams seeking reduced DevOps overhead without OS-level server control. In summary: align your approach with your actual architecture—Certbot on Droplets isn't the default for every case.
- Single Droplet with Nginx/Apache—Certbot is the most straightforward choice
- Multiple Droplets behind Load Balancer—use Load Balancer's Let's Encrypt integration ($12/month minimum)
- Need wildcard certificates—use DNS-01 via
certbot-dns-digitalocean - Using App Platform—SSL is automatic; no Certbot needed
Common Mistakes and How to Fix Them
From multiple reviews, beyond technical issues, process-level mistakes often trip up system administrators, creating problems worse than the initial setup.
First mistake: skipping auto-renewal testing after setup. Many install Certbot, issue certificates successfully, then never check again—until 90 days pass, the certificate expires, and browsers warn users. Solution: run sudo certbot renew --dry-run immediately after setup. Additionally, configure separate monitoring (DigitalOcean Monitoring or uptime checks) to alert if SSL issues arise.
Second: rebuilding or destroying a Droplet without backing up /etc/letsencrypt/ first. You'll need to reissue all certificates afterward—not catastrophic if you don't hit rate limits, but wasteful. Solution: regularly snapshot your Droplet with DigitalOcean Snapshots (costs $0.06/GiB/month), which includes certificate folders automatically. Or at minimum, manually back up this folder before major changes.
Third: manually editing web server config after Certbot sets it up, not realizing Certbot manages the SSL block automatically. This creates conflicting or overlapping config blocks. Safer approach: let Certbot handle all SSL-related sections; edit only non-certificate parts like location blocks and proxy passes.
Fourth: opening port 443 only in ufw without adding the corresponding rule to DigitalOcean Cloud Firewall, then wondering why users can't access HTTPS. Auto-renewal works fine using port 80, but real users connecting on 443 fail silently due to network-layer blocking. Solution: always verify both ufw and Cloud Firewall rules match whenever making changes.
- Skip auto-renewal testing—run and verify immediately after installation
- Rebuild Droplet without backing up
/etc/letsencrypt/—use Snapshots ($0.06/GiB/month) - Manually edit web server config over Certbot-managed sections—causes config conflicts
- Open port 443 only in ufw, not in Cloud Firewall—users can't reach HTTPS
Best Practices
After initial Let's Encrypt SSL setup on your Droplet, adopt these practices to maintain stability and security long-term—not just get it working the first time.
First: always use --staging when testing or debugging new configurations before requesting real certificates, avoiding unnecessary rate limit consumption. Particularly important when iterating through multiple Nginx/Apache config tweaks.
Second: enable HSTS (HTTP Strict Transport Security) after confirming HTTPS operates reliably, by adding the Strict-Transport-Security header to your web server config. This forces browsers to use HTTPS-only for future visits, even if users type http://. Test thoroughly first to ensure all subdomains support HTTPS, as misconfigured HSTS can temporarily block access.
Third: configure separate monitoring beyond Certbot's auto-renewal. Don't rely solely on Certbot's scheduled task. Use DigitalOcean Monitoring or third-party SSL expiry checks (like your control panel's built-in SSL checker) as a safety net. This alerts you immediately if renewal fails for any reason.
Fourth: employ --deploy-hook to automatically reload certificates after renewal, avoiding manual server restarts that could interrupt users.
Fifth: regularly back up /etc/letsencrypt/ via DigitalOcean Snapshots or separate storage, especially before OS upgrades or Droplet migrations, reducing the need to re-issue all certificates.
Last: keep Certbot updated to the latest version. Snap installations update automatically, but apt installations need manual updates via sudo apt update && sudo apt upgrade certbot. Let's Encrypt and ACME standards evolve for security; outdated Certbot versions risk compatibility problems in the future.
- Always use
--stagingduring testing to avoid hitting production rate limits - Enable HSTS only after confirming HTTPS is stable across all subdomains
- Configure separate monitoring for SSL expiry independent of auto-renewal
- Use
--deploy-hookto gracefully reload your web server - Back up
/etc/letsencrypt/via Snapshots before major changes
Frequently Asked Questions
certbot renew --dry-run for assurance.--staging during testing to avoid this.