
September 11, 2026
11 min read
By Kokil Thapa | Last reviewed: September 2026
Every production site needs valid TLS, and manual renewals fail quietly until browsers show warnings. To automate HTTPS with Lets Encrypt and Certbot, you install the ACME client once, prove domain control, and schedule renewals before the 90-day expiry. I've maintained dozens of Ubuntu servers for Linux system administration clients in Nepal and abroad using this exact stack. This guide covers Apache and Nginx on Ubuntu 22.04/24.04 with copy-paste commands you can run today.
What is Let's Encrypt and how does Certbot automate HTTPS?
Let's Encrypt is a free, automated certificate authority run by the Internet Security Research Group. It issues domain-validated TLS certificates through the ACME protocol. Certbot is the official EFF client that talks to Let's Encrypt on your behalf.
Automation means three things in practice. First, initial issuance proves you control the hostname. Second, scheduled renewals repeat that proof before expiry. Third, a deploy hook reloads Apache or Nginx so visitors immediately get the new certificate.
On client projects I deploy with Ansible playbooks for server setup, Certbot is usually the last step after DNS and the web server are live. Treat TLS as infrastructure, not a launch-day afterthought. Browsers, search engines, and payment gateways all expect HTTPS in 2026.
Let's Encrypt certificates expire after 90 days by design. That short lifetime pushes operators toward automation instead of calendar reminders. Certbot's default renewal window starts at 30 days before expiry, though most teams renew around day 60.
For background on the initial manual path, see the companion guides on HTTPS setup with Let's Encrypt and Certbot and setting up free SSL with Let's Encrypt. This article focuses on making renewals hands-off.
Why automation beats one-time setup
A single successful certbot certonly run does not protect you six months later. I've seen law-firm portals and eCommerce stores go offline on a Sunday because nobody tested renewal. Automation plus monitoring closes that gap.
How do you install Certbot on Ubuntu for Apache or Nginx?
On Ubuntu 22.04 or 24.04, use the distribution packages or Snap. Both work in production. I prefer the Snap package on fresh servers because it tracks upstream Certbot releases closely.
Install via Snap (recommended on Ubuntu)
sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
sudo ln -sf /snap/bin/certbot /usr/bin/certbot
certbot --version Confirm you see a recent Certbot release before proceeding. The Snap package bundles its own dependencies, which reduces conflicts with system Python.
Install via apt
sudo apt update
sudo apt install certbot python3-certbot-nginx
sudo apt install python3-certbot-apache Install only the plugin package matching your web server. The Nginx plugin rewrites server blocks. The Apache plugin edits virtual host files.
Pre-flight checklist before any certificate request
- DNS A/AAAA records point to this server's public IP.
- Ports 80 and 443 are open in UFW or your cloud security group.
- The virtual host serves the correct
server_nameon port 80. - No CDN orange-cloud proxy blocks direct HTTP validation unless you use DNS-01.
Domain and hosting decisions matter here. If DNS still propagates, wait before running Certbot. Our domain registration and hosting service usually confirms records before TLS work begins.
Which Certbot plugin should you use: webroot, standalone, or nginx/apache?
The plugin choice determines how Certbot proves domain control during HTTP-01 challenges. Pick the method that fits your downtime tolerance and server layout.
| Plugin | Best for | Downtime | Notes |
|---|---|---|---|
--nginx | Nginx sites on Ubuntu | None | Edits config and reloads automatically |
--apache | Apache virtual hosts | None | Works well with PHP-FPM stacks |
--webroot | Shared hosting, multiple apps | None | Writes token file under document root |
standalone | First cert before web server | Yes — binds port 80 | Stop Apache/Nginx temporarily |
dns-* | Wildcard certs, behind CDN | None | Needs API credentials at your DNS host |
On production Laravel and WordPress servers I usually run --nginx or --apache because the plugin handles both issuance and HTTPS redirects. Webroot is my fallback when the plugin cannot parse a complex config.
Nginx: fully automated first run
sudo certbot --nginx -d example.com -d www.example.com \
--agree-tos --email admin@example.com --redirect The --redirect flag adds an HTTP-to-HTTPS redirect. That single flag prevents duplicate-content SEO issues later. Pair it with canonical tags in your application layer.
Apache: fully automated first run
sudo certbot --apache -d example.com -d www.example.com \
--agree-tos --email admin@example.com --redirect After success, verify the new vhost with apachectl configtest and confirm PHP-FPM still serves dynamic pages. I've hit opcache stale paths after vhost rewrites — a quick FPM reload fixes it.
Webroot: when plugins fail
sudo certbot certonly --webroot -w /var/www/example.com/public \
-d example.com -d www.example.com \
--agree-tos --email admin@example.com Ensure Nginx or Apache already maps /.well-known/acme-challenge/ to that webroot. Without that location block, HTTP-01 validation fails every time.
The official Let's Encrypt challenge types documentation explains when to switch from HTTP-01 to DNS-01. Use DNS-01 for wildcard certificates like *.example.com.
How do you obtain and auto-renew a Let's Encrypt certificate with Certbot?
Initial issuance is half the job. Auto-renewal is what keeps HTTPS alive for years without manual touch.
Verify the renewal timer on Ubuntu
Snap and apt installs register a systemd timer automatically. Check it:
systemctl list-timers | grep certbot
sudo systemctl status certbot.timer You should see a twice-daily trigger. Certbot only renews certificates within 30 days of expiry, so most runs exit quickly with "no renewals were attempted".
Test renewal without applying changes
sudo certbot renew --dry-run Always run a dry-run after first issuance and after any Nginx or Apache config change. A passing dry-run is your best proof that automation works. Schedule this in your deployment checklist alongside automated server backups with rsync and cron.
Add deploy hooks to reload the web server
Renewal replaces files under /etc/letsencrypt/live/yourdomain/. The web server must reload to pick up the new fullchain.
sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy
sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-webserver.sh Example hook for Nginx:
#!/bin/bash
nginx -t && systemctl reload nginx sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-webserver.sh For Apache, swap the reload command:
#!/bin/bash
apachectl configtest && systemctl reload apache2 On sister sites sharing a Deployer 7 pipeline — including Notary Kathmandu and similar legal-tech portals — I run the dry-run after every deploy that touches vhost files.
Fallback cron entry (if no systemd timer)
0 3,15 * * * certbot renew --quiet --deploy-hook "systemctl reload nginx" Running twice daily gives you room to fix failures before the 90-day cliff. Log output to a file if you want email alerts on failure.
Certificate file locations your app may reference
/etc/letsencrypt/live/example.com/fullchain.pem— send this to browsers/etc/letsencrypt/live/example.com/privkey.pem— keep permissions at 600/etc/letsencrypt/live/example.com/chain.pem— intermediate chain for some proxies
Never copy private keys into your Git repository. Reference the live symlink path in server config only. For generating strong passphrases for unrelated secrets, use the password generator tool — but never for TLS keys managed by Certbot.
HTTP/2 and HTTP/3 performance gains only matter once TLS is stable. After automation works, read HTTP/2 vs HTTP/3 and QUIC for the next tuning step.
How do you troubleshoot Certbot auto-renewal failures in production?
Renewal failures are silent until expiry nears. Build habits that surface problems early.
Common failure causes and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Connection refused on port 80 | Firewall or Nginx not listening | Open UFW port 80; verify ss -tlnp | grep :80 |
| 404 on challenge URL | Missing webroot or wrong server_name | Add /.well-known/ location block |
| Too many requests | Hit Let's Encrypt rate limit | Use staging first; wait one week |
| DNS problem | Domain moved to new IP | Update A record; flush CDN cache |
| Renew succeeds, site still broken | No deploy hook reload | Add reload script under renewal-hooks |
Our dedicated article on Let's Encrypt auto-renewal common failures walks through real log excerpts. Start every investigation with:
sudo certbot renew --dry-run -v
sudo tail -100 /var/log/letsencrypt/letsencrypt.log Use the staging environment for experiments
sudo certbot --nginx -d test.example.com --staging --dry-run Staging certificates are not trusted by browsers. They do not count against production rate limits. Test config rewrites there first.
Rate limits you should know
- 50 certificates per registered domain per week
- 5 duplicate certificates per week for the same hostname set
- 300 new orders per account per 3 hours
Agencies managing many client subdomains should centralise account keys carefully. Wildcard certs via DNS-01 reduce hostname sprawl. The Certbot official installation instructions list supported DNS provider plugins.
Multi-domain and Laravel-specific notes
Laravel apps behind Nginx often use a single public/ webroot. Point Certbot's webroot flag there. Ensure APP_URL in .env uses https:// after redirect is enabled.
For WooCommerce or custom eCommerce stacks, mixed-content warnings usually mean hard-coded http:// asset URLs. Fix those in the database or config — the certificate itself is fine. See Quick And Easy Nepalese Grocery and similar Laravel eCommerce work for HTTPS-first deployment patterns.
Monitoring complements automation. Add an external uptime check that alerts 14 days before certificate expiry. Many teams pair this with support and maintenance plans so renewal regressions get caught during routine server reviews.
Hard-fail practices to avoid
- Disabling port 80 after obtaining a certificate — HTTP-01 renewal needs it
- Deleting
/etc/letsencryptduring server migrations without backing up keys - Running Certbot on multiple servers against the same hostname simultaneously
- Ignoring failed dry-runs because "the site still loads today"
Website migrations need a deliberate TLS cutover plan. Our website migration service re-runs Certbot on the destination before DNS flips.
Key Takeaways
- Install Certbot via Snap or apt, then choose the plugin matching your web server:
--nginx,--apache, or--webroot. - Run
certbot renew --dry-runafter every vhost change and after initial issuance to confirm automation works. - Add a deploy hook that runs
nginx -torapachectl configtestbefore reload so bad configs never go live. - Keep port 80 open permanently — HTTP-01 validation and redirects both depend on it.
- Monitor expiry externally; systemd timers fail quietly if the server clock drifts or disk fills up.
- Use Let's Encrypt staging when testing new domains to avoid production rate limits.
People Also Ask
Does Let's Encrypt auto-renew for free?
Yes. Let's Encrypt certificates cost nothing and Certbot renews them automatically via systemd timer or cron. You pay only for server time and the engineering to configure it correctly.
How often does Certbot renew certificates?
Certbot checks twice daily but only renews certificates within 30 days of their 90-day expiry. Most successful renewals happen around day 60, giving you a month to fix failures.
Can I automate HTTPS with Certbot on shared hosting?
Only if your host allows shell access and custom TLS configuration. Webroot mode works when you can write to the document root and serve /.well-known/acme-challenge/ over HTTP.
What happens if auto-renewal fails?
The existing certificate keeps working until it expires. Browsers then show security warnings and search rankings may suffer. Fix the root cause, pass a dry-run, and confirm the deploy hook reloads your server.
Ship HTTPS automation you can forget about
Manual certificate management does not survive busy launch schedules or holiday weekends. When you automate HTTPS with Lets Encrypt and Certbot, you get free TLS, predictable renewals, and one less production fire drill every quarter. Start with a clean dry-run, add deploy hooks, and keep port 80 alive.
Need help hardening TLS across Apache, Nginx, or a multi-site Deployer pipeline? Review our web development services, browse the Court Marriage in Nepal portfolio for live HTTPS examples, or contact us to audit your current certificate setup.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

