This guide shows you how to secure Nginx 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
- Nginx installed and running
- 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 Nginx Server Block
Before requesting a certificate, Certbot needs to find your domain in the Nginx configuration. If you haven’t already, create a server block for your domain:
sudo nano /etc/nginx/sites-available/example.com
Add a basic configuration:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html index.php;
}
Enable the site and test the configuration:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
If nginx -t shows errors, fix them before continuing. Certbot will fail if Nginx can’t reload.
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 Nginx 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 Nginx 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 --nginx plugin. This automatically verifies your domain, gets the certificate, updates your Nginx config, and sets up an HTTP-to-HTTPS redirect:
sudo certbot --nginx -d example.com -d www.example.com --non-interactive --agree-tos --no-eff-email --redirect -m you@example.com
-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 a 301 redirect from HTTP to HTTPS 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 Nginx Configuration
Certbot modifies your server block automatically. Open it to confirm the SSL directives were added:
sudo nano /etc/nginx/sites-available/example.com
You should see a block like this for HTTPS:
server {
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
root /var/www/example.com;
index index.html index.php;
}
And a redirect block for HTTP:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
Test and reload:
sudo nginx -t && sudo systemctl reload nginx
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:
- “Could not automatically find a matching server block” — your
server_namein the Nginx config doesn’t match the-ddomain you passed to Certbot. Fix the config and reload Nginx before retrying. - “Problem binding to port 80” — another process is using port 80, or Nginx 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 DNS propagation with
dig example.com. - Rate limits — Let’s Encrypt allows 5 duplicate certificates per domain per week. If you hit this limit during testing, wait or use the
--stagingflag to test without rate limits.
Conclusion
Your Nginx server now serves traffic over HTTPS with a free Let’s Encrypt certificate that renews automatically. If you’re also running Apache on other servers, see How to Secure Apache2 with Let’s Encrypt on Ubuntu 22.04. For a full WordPress setup behind Nginx with SSL, check out How to Install WordPress on EC2 Ubuntu 22.04.


