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 sudo or root access.
  • Your domain points to the server’s public IP address.
  • Ports 80 and 443 are 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:

  1. Detect your Apache configuration.
  2. Ask for your email address.
  3. Ask you to accept the Let’s Encrypt Terms of Service.
  4. Ask which domains should use HTTPS.
  5. Obtain the SSL certificate.
  6. Update the Apache VirtualHost configuration.
  7. 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:

CommandPurpose
certbot --versionCheck Certbot version
sudo certbot certificatesList certificates
sudo certbot --apacheConfigure SSL for Apache
sudo certbot --nginxConfigure SSL for Nginx
sudo certbot certonlyObtain certificate without configuring web server
sudo certbot renewRenew certificates
sudo certbot renew --dry-runTest renewal
sudo certbot renew --force-renewalForce renewal
sudo certbot delete --cert-name example.comDelete certificate
sudo systemctl status snap.certbot.renew.timerCheck automatic renewal timer

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 80 is accessible.
  • Port 443 is 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-run succeeds.
  • 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.