Run your own backend

Set up HTTPS for your app - free, and auto-renewing

The short version: get a free certificate from Let's Encrypt and let it auto-renew. The easiest path is Caddy, which obtains and renews TLS automatically with no flags. If you are on nginx, use certbot. Either way: point your domain's DNS at the server, open ports 80 and 443, run the tool once, and confirm renewal is scheduled - the step people forget.

Before you start

Three things have to be true or the certificate request will fail:

  • A domain you control (Let's Encrypt does not issue for bare IPs).
  • DNS pointed at the server - an A/AAAA record for the host resolving to its public IP.
  • Ports 80 and 443 open - 80 is used for the HTTP-01 challenge, 443 for HTTPS itself.

Two good paths

Caddy - automatic, simplest

HTTPS is on by default; Caddy obtains and renews certificates with no flags and no cron. Best if you are starting fresh.

nginx + certbot - more control

certbot obtains the cert and edits your nginx config; a systemd timer renews it. Best if you already run nginx.

Set it up

A

The Caddy way (automatic)

# /etc/caddy/Caddyfile - that is the whole config
example.com {
    reverse_proxy localhost:3000
}
# reload; Caddy fetches and renews the cert automatically
sudo systemctl reload caddy
B

The nginx + certbot way

sudo apt install certbot python3-certbot-nginx
# certbot obtains the cert and edits your nginx server block:
sudo certbot --nginx -d example.com -d www.example.com
C

Confirm auto-renewal

# certbot installs a timer - verify it and dry-run a renewal
systemctl list-timers | grep certbot
sudo certbot renew --dry-run
# Caddy renews internally - no timer needed.
Do not skip

Renewal, redirect, and modern TLS

A certificate is 90 days; the thing that keeps your site up is automatic renewal, so confirm it works rather than assuming. Then redirect HTTP to HTTPS so no one lands on the insecure version, and serve only modern TLS (1.2 and 1.3). Caddy does all of this by default; on nginx, certbot adds the redirect and you set ssl_protocols.

# nginx - redirect http -> https and pin modern TLS
server { listen 80; server_name example.com; return 301 https://$host$request_uri; }
# in the 443 server block:
ssl_protocols TLSv1.2 TLSv1.3;

Once HTTPS is live, audit the headers and config with the free security headers checker and nginx config checker, and make sure your app does not load any insecure http resources.

How Infraveil handles this

TLS that stays valid, on your servers

The risk with self-managed TLS is a renewal that silently fails and a cert that expires at 3am. On your own servers, Infraveil helps you stand up consistent HTTPS and proxy config and keeps it supervised - so a failed renewal is surfaced before the cert expires, the redirect and modern-TLS posture stay in place across hosts, and config changes are recorded.

Consistent HTTPS + redirect + modern TLS across hosts you own
Renewal supervised - a failure surfaced before the cert expires
Edge and TLS config changes recorded and inspectable

Frequently asked questions

Caddy or nginx + certbot - which should I use?

Caddy for the least work - automatic HTTPS, no cron. nginx + certbot if you already run nginx or need its features; certbot obtains the cert and a timer renews it. Both use Let's Encrypt and are free.

Is Let's Encrypt really free and safe?

Yes - a non-profit CA trusted by all major browsers, certificates free. The trade-off is 90-day validity, which is why automatic renewal matters; both Caddy and certbot handle it.

How does auto-renewal work, and how do I confirm it?

certbot installs a systemd timer (or cron); check with systemctl list-timers | grep certbot and test with certbot renew --dry-run. Caddy renews internally with no timer. A cert that does not auto-renew silently expires in 90 days.

Can I get a wildcard certificate?

Yes, for *.example.com, but it requires a DNS-01 challenge (a DNS-provider plugin and API token) rather than HTTP-01. Use one only if you need many subdomains; otherwise per-host certs are simpler.