Skip to content
Faizul Karim Fahim

Setting up Let's Encrypt with Nginx on Ubuntu

Getting HTTPS right can feel like a pain, but it doesn't have to be. I'll walk through setting up Let's Encrypt with Nginx on Ubuntu, so your sites are secure and you don't have to wrestle with certificate renewals.

Published 3 min read Security
Illustration of a padlock icon overlaying an Nginx logo on an Ubuntu server terminal.
On this page
  1. Prerequisites
  2. Installing Certbot
  3. Requesting the Certificate
  4. Automating Certificate Renewal
  5. My setup
  6. What went wrong (gotchas)
  7. Troubleshooting
  8. Related reading

Keeping your websites secure with HTTPS is no longer optional. I've been using Let's Encrypt for years, and it's made the process much easier. Here's how I set it up with Nginx on my Ubuntu servers, and on client boxes I usually manage.

Prerequisites

Make sure you have Nginx installed. If not, install it:

sudo apt update
sudo apt install nginx

Also, ensure your domain name points to your server's IP address. I usually check this with dig:

dig yourdomain.com

Installing Certbot

Certbot is the official Let's Encrypt client. Install it from the official repository. This is important; don't grab it from random places.

sudo apt update
sudo apt install certbot python3-certbot-nginx

Requesting the Certificate

Now, run Certbot to request the certificate. Replace yourdomain.com and www.yourdomain.com with your actual domain names:

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

Certbot will automatically configure Nginx to use the certificate. It will ask you a few questions, like whether you want to redirect HTTP traffic to HTTPS. I always choose to redirect. This is important for security.

If you have multiple domains, add them with -d flags. Certbot will handle it.

Automating Certificate Renewal

Let's Encrypt certificates are only valid for 90 days. Certbot sets up a systemd timer to automatically renew them, but it's good to test the renewal process:

sudo certbot renew --dry-run

This simulates a renewal without actually making any changes. If it fails, investigate the error messages. I find this is often a DNS issue.

My setup

On my servers, I prefer to use the --nginx plugin directly. Honestly, messing with the Nginx config manually is a recipe for errors.

For more complex setups, where I need to manage multiple certificates or use different configurations, I sometimes explore using the Certbot API. But for most small to medium sites, the command-line tool is more than enough.

What went wrong (gotchas)

  • DNS Propagation: Let's Encrypt validates your domain ownership through DNS. Make sure your DNS records are updated before running Certbot. I’ve spent hours debugging this.
  • Nginx Configuration: Certbot modifies your Nginx configuration files. Make sure you understand the changes it makes. I usually review the files in /etc/nginx/sites-available/ after Certbot runs.
  • File Permissions: The certificates are stored in /etc/letsencrypt/live/yourdomain.com/. Make sure Nginx has read access to these files. This is usually handled automatically, but it’s worth checking.
  • PHP-FPM Socket Path: If you're using PHP-FPM, make sure your PHP-FPM configuration (usually in /etc/php/8.3/fpm/pool.d/www.conf, adjust the PHP version as needed) is using the correct socket path. This is a common source of errors when HTTPS is enabled.
  • Systemd Timer: Verify that the Certbot systemd timer is enabled and running:
systemctl status certbot.timer
  • Ubuntu 24.04: The default Certbot package on Ubuntu 24.04 might use a different plugin path. If you encounter issues, try specifying the plugin explicitly: sudo certbot --nginx --plugin nginx-plugin -d yourdomain.com -d www.yourdomain.com.

Troubleshooting

  • Check Nginx Error Logs: Nginx error logs (/var/log/nginx/error.log) often contain clues about certificate-related issues.
  • Certbot Logs: Certbot logs its activity in /var/log/letsencrypt/. Examine these logs for errors.
  • DNS Propagation: Use a DNS propagation checker to verify that your DNS records have updated globally.

Setting up Let's Encrypt with Nginx on Ubuntu is a straightforward process. With a little care and attention to detail, you can easily secure your websites and automate certificate renewal. Just don’t skip the dry run renewal test, it's saved me a lot of headaches over the years.

I don't bother with complicated certificate management tools for smaller VPSes; Certbot does the job perfectly well.

Frequently asked questions

Why should I use HTTPS?

HTTPS encrypts data between your server and visitors' browsers, protecting sensitive information like passwords and credit card details. It also boosts your SEO and builds trust with your users.

What is Let's Encrypt?

Let's Encrypt is a free, automated, and open certificate authority. It makes getting and renewing SSL/TLS certificates simple and accessible for everyone.

Do I need a static IP address?

No, Let's Encrypt supports dynamic IPs, making it suitable for VPSes with changing IP addresses. However, DNS propagation can still take time.

// keep reading

Related posts

All blog posts
Illustration of a server with a shield and padlock, representing server security.
Security 4 min read

Server Hardening: SSH, Firewalls, and Fail2ban

Keeping my servers secure is always a priority, and a good starting point is tightening up SSH, configuring a basic firewall, and using Fail2ban to block brute-force attempts. It's not about perfect security, but about making things harder for attackers.

Illustration of a Laravel logo being deployed to an Ubuntu server via GitHub Actions workflow.
DevOps 2 min read

Automating Laravel Deployments with GitHub Actions

Setting up automated deployments for my Laravel projects used to be a headache, but GitHub Actions has made it significantly easier. Here's how I automate deployments to Ubuntu servers using GitHub Actions, and some common gotchas I've run into along the way.