🇧🇷 Leia a versão em português aqui.
On traditional servers — a VPS hosting a static site, a standalone application server, or any machine outside the cluster — Certbot remains the most straightforward tool for issuing and renewing free Let's Encrypt TLS certificates.
This article covers the two most common scenarios: issuing a certificate for a specific domain served from a directory (webroot), and issuing a wildcard certificate, which covers a domain and all of its subdomains at once.
Issuing a certificate for a domain
If the application is already served by a web server (Apache, Nginx, etc.) pointing to a specific directory, the webroot method is the simplest: Certbot creates a temporary validation file inside that directory, which Let's Encrypt accesses over HTTP to confirm you control the domain.
certbot -v certonly --webroot -w /var/www/vhosts/oregon -d www.oregon.net.br
Where:
-
--webroot -w /var/www/vhosts/oregon: specifies the root directory where the site is already being served; -
-d www.oregon.net.br: the domain the certificate will be issued for.
Renewing certificates
Let's Encrypt certificates have a short validity period (90 days), so renewal needs to be a recurring process. To renew all certificates close to expiration at once:
certbot renew
To renew a specific domain:
certbot renew certonly -d www.oregon.net.br
Important: for this kind of procedure, especially when done via SSH on a VPS, it's recommended to use
screen(ortmux) before running the command — that way, if the connection drops midway through, the command keeps running in the background session, without needing to start over.
In practice, the most common way to handle renewal is to schedule certbot renew in a cron job, since Certbot only renews certificates that are actually close to expiring — running the command frequently causes no issue.
Issuing a wildcard certificate
When an application uses multiple subdomains (for example, api.bagarote.dev.br, adm.bagarote.dev.br, app.bagarote.dev.br), instead of issuing a separate certificate for each one, you can issue a single wildcard certificate that covers all subdomains at once.
Wildcard certificates require DNS validation (not HTTP), since there's no fixed web server behind *.domain:
certbot certonly -v --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory -d '*.bagarote.dev.br' -d bagarote.dev.br
When you run this command, Certbot will ask you to create a specific TXT record (_acme-challenge.bagarote.dev.br) in your domain's DNS, as proof that you control it.
Renewing the wildcard certificate
certbot certonly --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory -d '*.bagarote.dev.br' -d bagarote.dev.br --force-renewal --manual-public-ip-logging-ok
The --force-renewal flag forces the issuance of a new certificate even if the current one is still valid, and --manual-public-ip-logging-ok confirms you're aware that Let's Encrypt logs the public IP the validation was performed from.
Checking DNS record propagation
After creating the TXT record requested by Certbot, it's important to confirm it has already propagated before proceeding with validation — DNS can take a few minutes (or, in rare cases, hours) to propagate globally.
Online tools that help with this check:
Or, directly from the terminal:
dig TXT _acme-challenge.bagarote.dev.br
If the result returns the expected TXT value, the record has already propagated and Certbot's validation should proceed without issues.
Final thoughts
Unlike the automated flow with cert-manager inside a Kubernetes cluster, Certbot requires more manual intervention — especially for wildcard certificates, which depend on manually creating DNS records on every renewal (unless your DNS provider has an automation plugin compatible with Certbot, which eliminates this manual step). Still, for standalone servers outside the cluster, it's a reliable, free, and widely documented solution for keeping TLS certificates valid.
Top comments (0)