Secure a Subdomain With Let’s Encrypt and Nginx

Secure a subdomain with a free Let’s Encrypt certificate when its DNS record reaches the Nginx server that answers HTTP requests.

Before you request a certificate

Point an A or AAAA record for the subdomain at this server and make sure port 80 is reachable from the internet. HTTP-01 validation asks the certificate authority to fetch a temporary file from that hostname.

Use DNS-01 for a wildcard certificate or when you cannot expose port 80.

Install Certbot and its Nginx plugin

On Debian and Ubuntu systems that provide the packages, install Certbot with the Nginx plugin. Other distributions may use Snap or another supported package channel.

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

The plugin validates the Nginx configuration and can install certificate paths into the selected server block. The refresh environment ran Certbot 4.0.0 with the Nginx plugin installed.

Certbot 4.0.0 with the installed Nginx plugin
Certbot reports the installed Nginx authenticator and installer plugin.

Create an HTTP server block for the subdomain

Start with an HTTP virtual host whose server_name matches the subdomain and can serve the ACME challenge path before HTTPS is enabled.

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
    }
}

Run nginx -t before reloading Nginx, as the refresh environment accepted the same server_name and challenge-location structure.

sudo nginx -t
sudo systemctl reload nginx

Request and install the certificate

Run Certbot after the HTTP site is reachable so it can select the matching server block and add the HTTPS configuration.

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

Keep HTTP available until validation completes because HTTP-01 uses port 80, even when the final site only serves HTTPS.

Test renewal before you need it

Run Certbot’s renewal dry run after the first successful issue and after a major Nginx or DNS change.

sudo certbot renew --dry-run

Avoid copying certificate paths into a second Nginx server block unless you need a custom layout.

When DNS-01 is the better choice

Use DNS-01 for a wildcard certificate such as *.example.com or when your web server is behind a network boundary that cannot accept port 80 traffic. Add the requested TXT record at _acme-challenge.example.com, wait for DNS propagation, then continue the Certbot prompt.

sudo certbot certonly --manual --preferred-challenges dns -d "*.example.com" -d example.com

That manual command is useful for a one-time issue, not unattended renewal. Pick a DNS provider plugin or API-based hook when the certificate must renew without an operator editing TXT records.

Troubleshooting failed validation

A timeout usually means the hostname does not resolve to this server, port 80 is blocked, or a proxy intercepts the challenge request.

Check DNS and inspect active virtual hosts with nginx -T before another Certbot attempt.

Conclusion

The shortest safe path is an HTTP Nginx server block, the Certbot Nginx plugin, one certificate request, and a renewal dry run. Use DNS-01 only when its wildcard or network boundary support earns the extra DNS automation work.

Pankaj Kumar
Pankaj Kumar

Pankaj Kumar is the founder and CEO of CodeForGeek, with more than 14 years in IT. He is an open-source enthusiast who enjoys sharing what he learns through CodeForGeek and YouTube, with a focus on Python, data analytics, machine learning, Angular, Node.js, and Kafka.

Articles: 335