How to Secure Nginx with Let's Encrypt on Ubuntu

Kubana Cloud · February 20, 2026 · Updated March 19, 2026 · 5 min read

Tutorials
How to Secure Nginx with Let's Encrypt on Ubuntu

Introduction

Let's Encrypt is a free, automated Certificate Authority that provides TLS/SSL certificates to enable HTTPS on your website. It removes the cost and complexity that traditionally came with securing a site.

Certbot is the recommended client for Let's Encrypt. It handles certificate issuance, Nginx configuration, and automatic renewal — all in a few commands.

This guide walks you through installing Certbot, obtaining a certificate for your domain, configuring Nginx to use it, and verifying that automatic renewal works.

Prerequisites

  • An Ubuntu server with a non-root user that has sudo privileges. See our Initial Server Setup with Ubuntu guide.
  • Nginx installed and running. If you haven't set it up yet, install it with:
    sudo apt update
    sudo apt install nginx -y
  • A registered domain name pointing to your server's public IP address. You need at least an A record for your domain (e.g., example.com) and ideally one for www.example.com as well. DNS changes can take time to propagate, so make sure this is done before proceeding.
  • UFW firewall configured to allow HTTP and HTTPS traffic:
    sudo ufw allow 'Nginx Full'
  • Remember to keep the port 80 open in the firewall for Certbot to renew the certificate otherwise it will fail.

Step 1 — Setting Up Your Nginx Server Block

Certbot needs to find the correct server block in your Nginx configuration to automatically configure SSL. It looks for a server_name directive that matches the domain you're requesting a certificate for.

Create a server block configuration for your domain:

sudo nano /etc/nginx/sites-available/example.com

Add the following configuration (replace example.com with your actual domain):

server {
    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;

    root /var/www/example.com/html;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}

Create the web root directory and a simple test page:

sudo mkdir -p /var/www/example.com/html
echo '<h1>Hello from Kubana Cloud</h1>' | sudo tee /var/www/example.com/html/index.html

Enable the server block by creating a symbolic link:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

Test the Nginx configuration for syntax errors and reload:

sudo nginx -t
sudo systemctl reload nginx

Verify that your domain loads over HTTP in a browser before continuing.

Step 2 — Installing Certbot

Install Certbot and its Nginx plugin using snap, which is the recommended installation method:

sudo snap install --classic certbot

Create a symbolic link so the certbot command is available system-wide:

sudo ln -s /snap/bin/certbot /usr/bin/certbot

Verify the installation:

certbot --version

Step 3 — Obtaining an SSL Certificate

Run Certbot with the Nginx plugin. It will automatically modify your Nginx configuration to serve the certificate and redirect HTTP to HTTPS:

sudo certbot --nginx -d example.com -d www.example.com

If this is your first time running Certbot, you'll be prompted to:

  1. Enter your email address — Used for renewal notifications and urgent security notices.
  2. Agree to the Let's Encrypt Terms of Service.
  3. Optionally share your email with the EFF.

Certbot then communicates with the Let's Encrypt servers, runs a domain validation challenge, and if successful, downloads the certificate and updates your Nginx configuration automatically.

You should see output similar to:

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

Your Nginx server block will now include SSL directives and an HTTP-to-HTTPS redirect. You can inspect what Certbot changed:

sudo cat /etc/nginx/sites-available/example.com

You'll see that Certbot added listen 443 ssl, paths to the certificate files, and a redirect block for port 80.

Step 4 — Verifying HTTPS

Open your browser and navigate to your domain using https://:

https://example.com

You should see a padlock icon in the address bar confirming the connection is secure.

You can also test your SSL configuration using an external tool like SSL Labs. Enter your domain and it will give you a detailed grade. With Certbot's default configuration, you should receive an A rating.

Step 5 — Verifying Automatic Renewal

Let's Encrypt certificates are valid for 90 days, but Certbot sets up a systemd timer (or cron job) that automatically renews certificates before they expire. You don't need to do this manually.

Verify that the renewal timer is active:

sudo systemctl status snap.certbot.renew.timer

You should see output showing the timer is active and when the next renewal check is scheduled.

You can also do a dry run to make sure the renewal process works correctly:

sudo certbot renew --dry-run

If this command completes without errors, your certificates will renew automatically when needed.

Step 6 — Understanding the Certificate Files

Certbot stores your certificates under /etc/letsencrypt/live/your_domain/. Here's what each file is:

  • fullchain.pem — Your certificate plus the intermediate certificate chain. This is what Nginx serves to browsers.
  • privkey.pem — Your certificate's private key. Keep this secure and never share it.
  • cert.pem — Your domain certificate only.
  • chain.pem — The intermediate certificate(s) from Let's Encrypt.

If you need to reference these files in other applications (e.g., a Node.js or Go HTTPS server), use fullchain.pem and privkey.pem.

Conclusion

Your Nginx server is now secured with a free TLS/SSL certificate from Let's Encrypt. Traffic is encrypted, HTTP requests are automatically redirected to HTTPS, and certificate renewal is handled for you.

If you're deploying a Laravel application behind Nginx, your server block might look something like this with SSL already in place:

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    root /var/www/example.com/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

For more information, refer to the official Certbot documentation and the Let's Encrypt documentation.

Attachments

Back to all articles
Newsletter

Stay in the loop

Product updates, infrastructure insights, and platform news delivered to your inbox.