Let’s Encrypt provides free, automated SSL/TLS certificates that can be used to enable HTTPS on an Ubuntu server. Certbot is one of the most popular tools for obtaining and automatically renewing Let’s Encrypt certificates.
This guide covers installing Certbot, configuring SSL for Apache and Nginx, testing HTTPS, automatic renewal, and common troubleshooting commands.
Prerequisites
Before installing Certbot, make sure:
- You have an Ubuntu server.
- You have
sudoorrootaccess. - Your domain points to the server’s public IP address.
- Ports
80and443are accessible from the Internet. - Your web server is already configured for the domain.
You can verify DNS resolution with:
dig +short example.com
Or:
nslookup example.com
Replace example.com with your actual domain.
Install Certbot
On modern Ubuntu versions, the recommended approach is to install Certbot using Snap.
First, make sure Snap is available:
sudo apt update
sudo apt install snapd
Install the Certbot package:
sudo snap install snapd
sudo snap refresh snapd
Then install Certbot:
sudo snap install --classic certbot
Create a symbolic link so that certbot is available from the standard command path:
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Verify the installation:
certbot --version
You should see output similar to:
certbot 5.x.x
Get SSL Certificate for Apache
If you are using Apache, Certbot can automatically detect your VirtualHost configuration and update it to use HTTPS.
Run:
sudo certbot --apache
Certbot will:
- Detect your Apache configuration.
- Ask for your email address.
- Ask you to accept the Let’s Encrypt Terms of Service.
- Ask which domains should use HTTPS.
- Obtain the SSL certificate.
- Update the Apache VirtualHost configuration.
- Optionally configure HTTP → HTTPS redirection.
After completion, open:
https://example.com
Your website should now be accessible over HTTPS.
Apache Certificate for a Specific Domain
You can also explicitly specify the domain:
sudo certbot --apache -d example.com -d www.example.com
This requests a certificate covering both:
example.com
www.example.com
Get SSL Certificate for Nginx
For Nginx, use:
sudo certbot --nginx
Certbot will detect the Nginx server configuration and configure HTTPS automatically.
You can also specify domains explicitly:
sudo certbot --nginx -d example.com -d www.example.com
After the certificate is installed, test:
https://example.com
Certificate-Only Installation
Sometimes you don’t want Certbot to modify your web server configuration.
In that case, you can use:
sudo certbot certonly --webroot -w /var/www/example.com -d example.com
For multiple domains:
sudo certbot certonly \
--webroot \
-w /var/www/example.com \
-d example.com \
-d www.example.com
The certificate files will normally be stored under:
/etc/letsencrypt/live/example.com/
The important files are:
cert.pem
chain.pem
fullchain.pem
privkey.pem
For most web server configurations, you will use:
fullchain.pem
privkey.pem
SSL Certificate Location
List all Let’s Encrypt certificates:
sudo ls -la /etc/letsencrypt/live/
For a specific domain:
sudo ls -la /etc/letsencrypt/live/example.com/
You can inspect the certificate:
sudo certbot certificates
Example output:
Certificate Name: example.com
Domains: example.com www.example.com
Expiry Date: 2026-11-07 12:00:00+00:00
Certificate Path: /etc/letsencrypt/live/example.com/fullchain.pem
Private Key Path: /etc/letsencrypt/live/example.com/privkey.pem
Configure Apache Manually
If you installed the certificate using certonly, you can configure Apache manually.
Example HTTPS VirtualHost:
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
<Directory /var/www/example.com/public>
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>
Make sure the required Apache modules are enabled:
sudo a2enmod ssl
sudo a2enmod rewrite
Then test the configuration:
sudo apache2ctl configtest
Expected output:
Syntax OK
Restart Apache:
sudo systemctl restart apache2
Configure Nginx Manually
For Nginx, a typical HTTPS configuration looks like:
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com www.example.com;
root /var/www/example.com/public;
index index.html index.php;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
}
Test the Nginx configuration:
sudo nginx -t
Then reload Nginx:
sudo systemctl reload nginx
Redirect HTTP to HTTPS
After SSL is working, it is recommended to redirect HTTP traffic to HTTPS.
For Apache:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect permanent / https://example.com/
</VirtualHost>
Alternatively, Certbot can configure the redirect automatically:
sudo certbot --apache
For Nginx:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
Then:
sudo nginx -t
sudo systemctl reload nginx
Test SSL Renewal
Let’s Encrypt certificates have a limited validity period, so automatic renewal is important.
Before relying on automatic renewal, perform a dry run:
sudo certbot renew --dry-run
If everything is configured correctly, Certbot should report that the renewal simulation was successful.
Check Certbot Renewal Timer
When Certbot is installed through Snap, automatic renewal is normally handled by a systemd timer.
Check it with:
sudo systemctl list-timers | grep certbot
You can also check the service:
sudo systemctl status snap.certbot.renew.service
Check the timer:
sudo systemctl status snap.certbot.renew.timer
Manually Renew Certificates
To renew certificates that are close to expiration:
sudo certbot renew
Certbot automatically determines which certificates need renewal.
You generally do not need to manually specify every domain.
Force Renewal
If you specifically need to force certificate renewal:
sudo certbot renew --force-renewal
Use this carefully. There is normally no reason to force renewal on every run.
For normal server maintenance, prefer:
sudo certbot renew
Renew a Specific Certificate
You can first check the certificate name:
sudo certbot certificates
Then renew a specific certificate:
sudo certbot renew --cert-name example.com
Reload Apache or Nginx After Renewal
If your web server needs to reload after certificate renewal, you can use a Certbot deploy hook.
For Apache:
sudo certbot renew --deploy-hook "systemctl reload apache2"
For Nginx:
sudo certbot renew --deploy-hook "systemctl reload nginx"
A deploy hook runs only when a certificate is successfully renewed.
Check Certificate Expiry
You can inspect the certificate using OpenSSL:
sudo openssl x509 \
-in /etc/letsencrypt/live/example.com/fullchain.pem \
-noout \
-dates
Output:
notBefore=Aug 09 12:00:00 2026 GMT
notAfter=Nov 07 12:00:00 2026 GMT
You can also check the certificate directly from the server:
echo | openssl s_client \
-connect example.com:443 \
-servername example.com 2>/dev/null \
| openssl x509 -noout -dates
Check Which Certificate Is Being Served
This is particularly useful when multiple SSL certificates or web servers are configured.
Run:
echo | openssl s_client \
-connect example.com:443 \
-servername example.com 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates
This shows:
- Certificate subject
- Certificate issuer
- Certificate start date
- Certificate expiration date
List All Certbot Certificates
Use:
sudo certbot certificates
This is one of the most useful commands when managing multiple websites on the same Ubuntu server.
Delete an SSL Certificate
First list certificates:
sudo certbot certificates
Then delete the certificate:
sudo certbot delete --cert-name example.com
Important: deleting a certificate from Certbot does not necessarily remove or disable the corresponding Apache/Nginx configuration. Make sure your web server configuration no longer references the deleted certificate.
Common Certbot Troubleshooting
Port 80 Is Not Accessible
The HTTP-01 challenge commonly requires the domain to be reachable over HTTP.
Check whether Apache or Nginx is listening:
sudo ss -lntp | grep ':80'
Check firewall rules:
sudo ufw status
Allow HTTP and HTTPS if required:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Port 443 Is Not Accessible
Check:
sudo ss -lntp | grep ':443'
Then check:
sudo ufw status
Allow HTTPS:
sudo ufw allow 443/tcp
If your server is hosted on AWS, DigitalOcean, Azure, or another cloud provider, also check the provider’s firewall/security-group rules.
DNS Is Pointing to the Wrong Server
Check:
dig +short example.com
Compare the result with your server’s public IP address.
For www:
dig +short www.example.com
Both DNS records need to resolve to an appropriate server.
Apache Configuration Error
Run:
sudo apache2ctl configtest
Then inspect the logs:
sudo tail -f /var/log/apache2/error.log
Check the Apache service:
sudo systemctl status apache2
Nginx Configuration Error
Run:
sudo nginx -t
Then check:
sudo systemctl status nginx
And:
sudo tail -f /var/log/nginx/error.log
Certbot Logs
Certbot logs are stored under:
/var/log/letsencrypt/
View the latest log:
sudo ls -lt /var/log/letsencrypt/
You can inspect the main log:
sudo less /var/log/letsencrypt/letsencrypt.log
Check Certbot Version
certbot --version
Check where Certbot is installed:
which certbot
If installed through Snap:
snap list certbot
Useful Certbot Commands
Here is a quick reference:
| Command | Purpose |
|---|---|
certbot --version | Check Certbot version |
sudo certbot certificates | List certificates |
sudo certbot --apache | Configure SSL for Apache |
sudo certbot --nginx | Configure SSL for Nginx |
sudo certbot certonly | Obtain certificate without configuring web server |
sudo certbot renew | Renew certificates |
sudo certbot renew --dry-run | Test renewal |
sudo certbot renew --force-renewal | Force renewal |
sudo certbot delete --cert-name example.com | Delete certificate |
sudo systemctl status snap.certbot.renew.timer | Check automatic renewal timer |
Recommended SSL Setup Workflow
For a new Ubuntu server, a typical workflow is:
sudo apt update
sudo apt install snapd
Install Certbot:
sudo snap install --classic certbot
Create the command symlink:
sudo ln -s /snap/bin/certbot /usr/bin/certbot
For Apache:
sudo certbot --apache -d example.com -d www.example.com
Or for Nginx:
sudo certbot --nginx -d example.com -d www.example.com
Then test renewal:
sudo certbot renew --dry-run
Finally, verify the certificate:
sudo certbot certificates
Final Checklist
Before considering the SSL setup complete, verify:
- Domain DNS points to the correct server.
- Port
80is accessible. - Port
443is accessible. - Certbot is installed.
- SSL certificate has been issued.
- HTTPS works correctly.
- HTTP redirects to HTTPS.
- Apache/Nginx configuration passes its syntax check.
- Automatic renewal is enabled.
certbot renew --dry-runsucceeds.- Certificate expiration date is correct.
With Certbot and Let’s Encrypt, SSL certificates can be issued and renewed automatically without purchasing or manually replacing certificates. For Ubuntu servers hosting multiple Apache or Nginx websites, certbot certificates, certbot renew --dry-run, and the web-server configuration tests are especially useful commands to keep in your regular server-maintenance toolkit.
