Introduction
If your Apache server still serves pages over plain HTTP, browsers flag it as "Not Secure" and visitors think twice before typing anything. A free SSL certificate from Let's Encrypt fixes that in minutes: it encrypts traffic between your visitors and your server and turns on the padlock icon in the address bar. This tutorial shows you exactly how to install an SSL certificate on Apache running Ubuntu 24.04 or 22.04 using Certbot, the official Let's Encrypt client. You will go from an unencrypted site to full HTTPS with automatic certificate renewal, and you will know how to verify and troubleshoot it.
Prerequisites
- An Ubuntu 24.04 or 22.04 server with root or sudo access.
- Apache already installed and serving at least one site (
apache2package). - A registered domain name pointing to your server's public IP. Let's Encrypt validates domain ownership, so you need real DNS A records for the domain (and
wwwif you use it). This does not work onlocalhostor a bare IP address. - Port 80 (HTTP) and port 443 (HTTPS) reachable from the internet. Let's Encrypt's HTTP-01 challenge reaches your server on port 80 to verify the domain.
Quick note: If you don't have Apache installed yet, run sudo apt install apache2 first. Everything below assumes the default Apache install on Ubuntu.
Step 1: Update the server and confirm Apache is running
Start with fresh package lists and make sure Apache is up. An outdated package cache is the most common reason Certbot installs fail.
sudo apt update && sudo apt upgrade -y
sudo systemctl status apache2
The first command refreshes package metadata and applies pending updates. The second prints Apache's service state — look for active (running). If it isn't running, start it with sudo systemctl start apache2.
Step 2: Allow HTTPS traffic through the firewall
Ubuntu servers usually run UFW. Apache's packaged UFW profiles make this a one-liner, but remember Let's Encrypt also needs port 80 open during issuance (and it stays needed for renewals).
sudo ufw allow 'Apache Full'
sudo ufw status
The Apache Full profile opens both port 80 and port 443. If you don't use UFW, open those ports in your cloud provider's security group instead (AWS, DigitalOcean, and most VPS panels have a firewall section). Verify port 80 is reachable from outside before continuing, or the challenge in Step 5 will fail.
Step 3: Make sure your virtual host has the correct ServerName
Certbot reads your Apache virtual hosts to know which domains to certify. Your site's VirtualHost block must declare the domain in ServerName. Check the default site config:
sudo nano /etc/apache2/sites-available/000-default.conf
It should contain a block like this. Add or fix the ServerName line with your real domain:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
ServerAdmin webmaster@example.com
DocumentRoot /var/www/html
</VirtualHost>
Replace example.com with your domain. ServerName is the primary name Certbot will offer to certify; ServerAlias adds the www variant. Save the file (Ctrl+O, Enter, Ctrl+X in nano), then check the config syntax and reload Apache:
sudo apache2ctl configtest
sudo systemctl reload apache2
apache2ctl configtest validates your config files and prints Syntax OK — never skip this before a reload. Also confirm your DNS actually points at the server:
dig +short example.com
The output must be your server's public IP. If it shows an old IP or nothing, fix the DNS A record and wait for propagation before continuing.
Step 4: Install Certbot and its Apache plugin
On modern Ubuntu, Certbot ships in the official repositories, so there is no need for third-party PPAs:
sudo apt install certbot python3-certbot-apache -y
certbot is the Let's Encrypt client; python3-certbot-apache is the plugin that automatically edits your Apache configuration (adds the SSL vhost, points it at the certificates, and optionally sets up HTTP-to-HTTPS redirects). Install both in one command.
Step 5: Request and install the certificate
Now run Certbot. The --apache flag uses the Apache plugin, and -d lists the domains to include on the certificate:
sudo certbot --apache -d example.com -d www.example.com
Certbot will ask for an email address (used for expiry warnings) and ask you to agree to the terms of service. Then it asks whether to redirect HTTP to HTTPS — choose 2 (Redirect) so every visitor gets the encrypted version automatically.
Under the hood Certbot does three things: it proves you control the domain via an HTTP-01 challenge (it places a temporary file under /var/www/html/.well-known/acme-challenge/ and Let's Encrypt fetches it), it downloads the signed certificate into /etc/letsencrypt/live/example.com/, and it creates a new SSL virtual host (000-default-le-ssl.conf) with the certificate paths wired in. When it prints "Congratulations!", your site is on HTTPS.
Step 6: Verify automatic renewal works
Let's Encrypt certificates expire after 90 days. The certbot package on Ubuntu installs a systemd timer that renews certificates automatically twice a day, but you should confirm the renewal path is healthy:
sudo systemctl status certbot.timer
sudo certbot renew --dry-run
The first command shows the timer is active (waiting). The second performs a test renewal against Let's Encrypt's staging servers without touching your real certificate. If the dry run completes with "The dry run was successful", renewal is set up correctly and you can forget about expiries.
Verify it worked
- Browser check: open
https://example.com(replace with your domain). The address bar should show the padlock icon and no warnings. - Redirect check: visit
http://example.com— it should immediately redirect to the HTTPS version (that's the redirect you enabled in Step 5). - Certificate details from the terminal:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates -issuerThis prints the certificate's validity dates and issuer. The issuer should read
CN = R11, O = Let's Encrypt(the intermediate name changes occasionally, but it will be a Let's Encrypt CA). - External grade: run your domain through SSL Labs' test (search "SSL Labs test") — a fresh Certbot install on Apache typically scores an A.
Common issues and fixes
1. "Failed authorization procedure" / challenge failed
Let's Encrypt couldn't reach your server on port 80. Check three things in order: the DNS A record points to this server's IP (dig +short example.com), port 80 is open in UFW or the cloud firewall (sudo ufw status), and Apache is actually listening on port 80 (sudo ss -tlnp | grep :80). Cloudflare or another proxy in "proxied" mode can also break the challenge — temporarily disable proxying during issuance.
2. "Too many requests" / rate limit errors
Let's Encrypt allows 5 duplicate certificates per domain per week. If you were testing repeatedly, you hit the limit. Fix: wait a week, or test against the staging environment with sudo certbot --apache --staging -d example.com — staging has much higher limits and is the right place to experiment.
3. Mixed content warnings after enabling HTTPS
The padlock shows but the browser warns about insecure content. This means your HTML loads images, CSS, or scripts over http://. Fix the URLs in your site to be protocol-relative or absolute https://. In WordPress this is usually fixed by changing the site URL settings; in static HTML, search-and-replace http:// with https:// in your files.
4. Renewal fails months later with connection errors
Renewal uses the same HTTP-01 challenge, so it needs port 80 open forever — not just at issuance time. If you closed port 80 after setup, reopen it (sudo ufw allow 'Apache Full'). Also check the timer is still active with sudo systemctl status certbot.timer; it can get disabled by careless systemctl cleanup.
5. Apache fails to start after Certbot edits the config
Rare, but if it happens: run sudo apache2ctl configtest to see the exact error. Certbot keeps a backup of your original config at /etc/apache2/sites-available/000-default.conf (and rolls back the SSL vhost at 000-default-le-ssl.conf) — you can disable the SSL site with sudo a2dissite 000-default-le-ssl and restart to get back to plain HTTP, then investigate.
Conclusion
You now have a free, trusted SSL certificate on Apache with automatic renewal and HTTP-to-HTTPS redirects — the exact setup production sites use. Your visitors get the padlock, encrypted logins and forms, and a small SEO boost, since Google treats HTTPS as a ranking signal.
Need help securing a production server, migrating sites, or hardening Apache beyond SSL? XpertBees handles server setup, security, and maintenance for businesses — get in touch and we'll take it from here.



