
September 10, 2026
12 min read
By Kokil Thapa | Last reviewed: September 2026
Every production website needs HTTPS in 2026. Browsers flag HTTP as insecure, search engines reward encrypted pages, and payment gateways refuse plain-text checkout flows. If you run Laravel, WordPress, or a custom PHP app on Ubuntu, the fastest path is to set up free SSL with Let's Encrypt and Certbot. I've done this on dozens of client servers — from legal-tech portals to WooCommerce shops — and the process is straightforward once DNS, ports, and your web server config align. This guide walks through install, issuance, renewal, and the failures I see most often in the field.
certbot --apache or certbot --nginx, verify HTTPS, then enable automatic renewal via systemd timer or cron.What do you need before you set up free SSL with Let's Encrypt and Certbot?
Let's Encrypt issues Domain Validation (DV) certificates at no cost. Certbot is the official client that talks to the ACME protocol, proves you control the domain, and writes certificate files to disk. Before you run either tool, confirm four prerequisites.
- A registered domain with an A record (or AAAA for IPv6) pointing to your server's public IP.
- Port 80 open for HTTP-01 validation, or port 443 if you use TLS-ALPN-01.
- A working web server — Apache or Nginx — serving a response on that domain.
- Root or sudo access on Ubuntu 22.04 or 24.04 LTS.
On shared hosting in Nepal, your provider may offer a one-click SSL panel instead. For VPS or dedicated servers you manage yourself, Certbot is the standard. If you also handle domain registration and hosting setup, get DNS propagation right first. Use a DNS lookup tool or wait 15–60 minutes after changing records.
Certificates expire after 90 days. That short lifetime is intentional. It limits damage from compromised keys and forces automated renewal. Manual yearly renewals belong to the old paid-CA era. Plan for automation from day one.
How do you install Certbot on Ubuntu for Apache or Nginx?
Install Certbot through the official snap package or your distribution repository. Snap tracks current releases and is what the Certbot documentation recommends for most Linux systems.
Install via snap (recommended)
sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot For Apache plugin support, ensure Apache is running first. For Nginx, confirm your site block responds on port 80 before requesting a certificate.
Install via apt (alternative)
sudo apt update
sudo apt install certbot python3-certbot-apache
sudo apt install certbot python3-certbot-nginx Check the version after install:
certbot --version On production Laravel stacks I maintain, PHP 8.3 or 8.5 runs behind Apache with mod_proxy or Nginx as a reverse proxy. Certbot sits outside the app layer. It only manages TLS termination at the web server. See our LEMP stack guide if you are building the server from scratch.
How do you set up free SSL with Let's Encrypt and Certbot on Apache?
Apache with a valid VirtualHost is the simplest path on Ubuntu servers I admin daily. Certbot reads your existing vhost, injects SSL directives, and reloads Apache.
- Create a VirtualHost on port 80 with
ServerNamematching your domain. - Confirm the site loads at
http://yourdomain.com. - Run Certbot with the Apache plugin.
- Test HTTPS and HTTP-to-HTTPS redirect.
Example VirtualHost before SSL:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example/public
<Directory /var/www/example/public>
AllowOverride All
Require all granted
</Directory>
</VirtualHost> Issue the certificate interactively:
sudo certbot --apache -d example.com -d www.example.com Certbot asks for an email address, agrees to terms, and optionally shares your email with the Electronic Frontier Foundation. Choose redirect when prompted — it adds a permanent 301 from HTTP to HTTPS. That redirect matters for technical SEO. Google treats the HTTP and HTTPS versions as duplicates without it.
Non-interactive mode suits CI and server provisioning scripts:
sudo certbot --apache \
-d example.com -d www.example.com \
--non-interactive --agree-tos \
-m admin@example.com --redirect Certificate files land in /etc/letsencrypt/live/example.com/. Apache references them through symlinks Certbot writes into your SSL vhost. Never copy those files manually — always let Certbot manage paths.
How do you set up free SSL with Let's Encrypt and Certbot on Nginx?
Nginx needs a server_name block listening on port 80 before Certbot can complete HTTP-01 validation. If you terminate TLS at Nginx and proxy to PHP-FPM, the pattern is the same.
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
} Issue the certificate:
sudo certbot --nginx -d example.com -d www.example.com Certbot adds a second server block on port 443 with ssl_certificate and ssl_certificate_key directives. It also configures the HTTP-to-HTTPS redirect. For advanced proxy setups — multiple backends, WebSocket headers — read our reverse proxy with Nginx guide.
Manual certificate-only mode works when you prefer to edit Nginx yourself:
sudo certbot certonly --webroot \
-w /var/www/example/public \
-d example.com -d www.example.com Then reference the cert paths in your own SSL server block:
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; Reload Nginx after any manual edit:
sudo nginx -t && sudo systemctl reload nginx | Method | Best for | Certbot command | Config changed by |
|---|---|---|---|
| Apache plugin | Laravel/PHP on mod_php or proxy | certbot --apache | Certbot edits vhost |
| Nginx plugin | LEMP, reverse proxy | certbot --nginx | Certbot edits server block |
| Webroot | Custom configs, Docker | certbot certonly --webroot | You edit manually |
| Standalone | No web server yet, port 80 free | certbot certonly --standalone | Temp listener only |
Standalone mode stops anything on port 80 temporarily. Use it during initial server setup before Apache or Nginx goes live. Never run standalone on a production box serving traffic.
How do you automate Let's Encrypt certificate renewal with Certbot?
Let's Encrypt certificates expire every 90 days. Certbot renews them when 30 days or less remain. The snap package installs a systemd timer automatically. Verify it:
sudo systemctl status certbot.timer
sudo systemctl list-timers | grep certbot Test renewal without actually replacing the cert:
sudo certbot renew --dry-run A successful dry run means your cron or timer will work silently for years. I've seen law-firm sites go dark because nobody tested renewal after a server migration. Our auto-renewal failures article covers the full diagnostic list.
Hook scripts for zero-downtime reload
After renewal, the web server must reload to pick up new certificate files. Certbot deploy hooks handle this:
sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy
sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-webserver.sh #!/bin/bash
systemctl reload apache2
systemctl reload nginx sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-webserver.sh On sister sites I deploy with Deployer 7 and GitLab CI, renewal runs on the server independently of application deploys. TLS and app releases should not share a pipeline step. Keep them separate.
What are common Certbot and Let's Encrypt errors in production?
Most failures are environmental, not Certbot bugs. Fix the underlying condition and re-run the same command.
DNS and connectivity failures
NXDOMAIN or wrong IP: The domain does not resolve to your server. Check A records at your registrar or Cloudflare panel. Propagation can take up to 48 hours across rare resolvers.
Connection refused on port 80: UFW or cloud security groups block inbound HTTP. Open the port:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload AWS, DigitalOcean, and local Nepali VPS providers all have network-level firewalls separate from UFW. Check both layers.
Rate limits
Let's Encrypt allows 50 certificates per registered domain per week. Staging helps during development:
sudo certbot --apache --staging -d test.example.com The staging CA issues untrusted certs. Use it to validate your automation before hitting production limits. Full rate limit docs live on the Let's Encrypt website.
Webroot and permission issues
HTTP-01 places a file at /.well-known/acme-challenge/. If Nginx serves a custom 404 or Laravel catches all routes, validation fails. Add a dedicated location block:
location ^~ /.well-known/acme-challenge/ {
root /var/www/certbot;
allow all;
} File ownership matters too. Certbot often runs as root but your app runs as www-data. Mismatched permissions on /etc/letsencrypt/archive/ break reloads after renewal.
Mixed content and HSTS
After SSL works, audit pages for hard-coded http:// asset URLs. Browsers block mixed content on secure pages. Add HSTS only when you are confident HTTPS is stable everywhere:
# Apache — inside SSL VirtualHost
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" HSTS with a broken subdomain locks users out until the cert is fixed. Test on staging first. Our staging environment guide explains how to mirror TLS settings safely.
For multi-domain setups — apex plus www plus staging — use a single certificate with multiple -d flags or separate certs per vhost. Wildcard certs require DNS-01 validation through a DNS provider plugin. That path needs API credentials at Cloudflare or Route53. HTTP-01 cannot issue wildcards.
After HTTPS is live, harden the rest of the stack. Generate strong database and admin passwords with our password generator tool. Schedule periodic testing and optimization passes that include SSL Labs scans and Core Web Vitals checks.
On a recent notary service portal migration, the old host still answered on port 80 for the same domain during DNS cutover. Let's Encrypt validated against the wrong server and issuance failed twice before TTL expired. Patience and a lower TTL before migration prevent that loop.
If you need a deeper walkthrough with alternate validation methods, the companion post on HTTPS setup with Let's Encrypt covers overlapping ground from a security-first angle. For ongoing server care after go-live, support and maintenance plans typically include renewal monitoring and expiry alerts.
Key Takeaways
- Point DNS to your server and open ports 80 and 443 before running Certbot — most failures start there.
- Use
certbot --apacheorcertbot --nginxfor automatic vhost configuration on Ubuntu. - Run
certbot renew --dry-runafter every server change to confirm automation still works. - Enable HTTP-to-HTTPS redirects immediately — they protect SEO and stop mixed-scheme duplicate URLs.
- Keep TLS management separate from application deploys; renewals should not depend on a code release.
- Test with the Let's Encrypt staging CA during development to avoid weekly rate limits.
People Also Ask
Is Let's Encrypt really free for commercial websites?
Yes. Let's Encrypt issues DV certificates at no charge for any domain, including commercial sites. There is no per-seat or per-domain fee. You pay only for server and admin time. Extended Validation (EV) certs from paid CAs still exist for specific compliance niches, but most Laravel, WordPress, and eCommerce sites do not need them.
How long does a Let's Encrypt certificate last?
Each certificate is valid for 90 days. Certbot auto-renews when 30 days or less remain. Shorter lifetimes improve security by limiting key exposure windows. They also push operators toward automation instead of manual yearly renewals.
Can I use Certbot on Windows or cPanel hosting?
Certbot targets Linux servers with root access. Windows IIS has ACME clients like win-acme. cPanel and Plesk panels often include AutoSSL or built-in Let's Encrypt buttons. On raw Ubuntu VPS instances — common for Nepali businesses — Certbot via snap is the standard approach.
What happens if my Let's Encrypt certificate expires?
Browsers show a full-page security warning. Users cannot proceed easily on modern Chrome or Firefox. API clients and webhooks may fail silently. Monitoring tools should alert at 14 days before expiry. Never rely on human calendar reminders alone.
Ship HTTPS the Right Way on Your Next Project
Free TLS is no longer optional — it is baseline infrastructure. When you set up free SSL with Let's Encrypt and Certbot correctly, you get trusted encryption, better search visibility, and fewer support tickets from browser warnings. The commands take minutes. DNS alignment, firewall rules, and renewal testing take careful attention. If you want hands-off server setup — from web development through TLS hardening and speed optimization — reach out via contact us or browse the portfolio for live examples. You can also read more on the blog or learn about my background on about me.
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.

