This guide shows you how to secure Apache2 with a free SSL certificate from Let’s Encrypt on Ubuntu 22.04 using Certbot. By the end, your site will serve traffic over HTTPS with automatic certificate renewal.
Prerequisites
- An Ubuntu 22.04 server with a public IP — follow How to Deploy EC2 Ubuntu 22.04 LTS on AWS if you need one
- Apache2 installed and running — see How to Install Apache 2.4 Web Server on EC2 Ubuntu 22.04 LTS
- A domain name with DNS A records pointing to your server’s public IP (both
example.comandwww.example.com) - Port 80 and 443 open in your firewall or security group
Step 1: Set Up Your Apache Virtual Host
Certbot reads your Apache config to find the domain it needs to secure. Make sure you have a VirtualHost for your domain:
sudo nano /etc/apache2/sites-available/example.com.conf
Add a basic configuration:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
<Directory /var/www/example.com/>
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Enable the site and reload Apache:
sudo a2ensite example.com.conf
sudo apache2ctl configtest && sudo systemctl reload apache2
If configtest shows Syntax OK, you’re ready for the next step.
Step 2: Install Certbot via Snap
The Certbot team recommends installing via snap instead of apt. The snap package stays up to date automatically and is the officially supported method.
Remove any old Certbot packages
If you previously installed Certbot through apt, remove it first to avoid conflicts:
sudo apt remove certbot -y
Install Certbot with the Apache plugin
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/local/bin/certbot
snap install --classic certbot— installs Certbot with full system access (needed to modify Apache configs and write certificates)ln -s— creates a symlink so you can runcertbotfrom anywhere
Step 3: Obtain and Install the SSL Certificate
Run Certbot with the --apache plugin. This verifies your domain, gets the certificate, updates your Apache config, and sets up an HTTP-to-HTTPS redirect:
sudo certbot --apache -d example.com -d www.example.com --non-interactive --agree-tos --no-eff-email --redirect -m you@example.com
--apache— uses the Apache plugin to handle config changes automatically-d— the domain names to secure (include both root and www)--non-interactive— runs without prompts--agree-tos— accepts the Let’s Encrypt terms of service--no-eff-email— skips the EFF newsletter signup--redirect— adds HTTP-to-HTTPS redirect automatically-m— email address for renewal notices and urgent security alerts
If successful, you’ll see output like:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/example.com/privkey.pem
Step 4: Verify the Apache Configuration
Certbot creates a new SSL VirtualHost file. Check it:
sudo nano /etc/apache2/sites-available/example.com-le-ssl.conf
You should see a VirtualHost block on port 443 with SSL directives:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
Certbot also adds redirect rules to your original port 80 VirtualHost using mod_rewrite, so all HTTP traffic is forwarded to HTTPS.
Test and reload:
sudo apache2ctl configtest && sudo systemctl reload apache2
Step 5: Test HTTPS and Auto-Renewal
Open https://example.com in your browser. You should see the padlock icon confirming HTTPS is active. Also try http://example.com to verify it redirects to HTTPS.
Let’s Encrypt certificates expire every 90 days. The Certbot snap package includes a systemd timer that checks for renewal twice a day. Test that it works:
sudo certbot renew --dry-run
If the dry run completes without errors, renewal is working. No cron job needed — the snap handles it.
Troubleshooting
Common issues and quick fixes:
- “Unable to find a virtual host” — your
ServerNamein the Apache config doesn’t match the-ddomain you passed to Certbot. Fix the VirtualHost and reload Apache before retrying. - “Problem binding to port 80” — another process is using port 80, or Apache isn’t running. Check with
sudo ss -tlnp | grep :80. - “DNS problem: NXDOMAIN” — your domain’s A record doesn’t point to this server’s IP yet. Verify with
dig example.com. - Rate limits — Let’s Encrypt allows 5 duplicate certificates per domain per week. Use the
--stagingflag when testing to avoid hitting limits. - mod_ssl not enabled — Certbot needs
mod_ssl. Enable it withsudo a2enmod ssl && sudo systemctl restart apache2.
Conclusion
Your Apache2 server now serves traffic over HTTPS with a free Let’s Encrypt certificate that renews automatically. If you’re running Nginx on other servers, see How to Secure Nginx with Let’s Encrypt on Ubuntu 22.04. To set up monitoring on your Apache server, check out How to Install Datadog Agent with Apache2 on EC2 Ubuntu 22.04.


