SSL Certificate Renewal Notes

SSL Certificate Renewal Notes

This note records a simple SSL certificate workflow with certbot: acquire, verify, renew, and deploy.

The example domain is api.example.com. Replace it with your own domain.

Acquire A Certificate

For a standalone HTTP-01 challenge, port 80 must be reachable and not occupied by another process:

1
sudo certbot certonly --standalone -d api.example.com

If Caddy or Nginx is already using port 80, stop it temporarily:

1
2
3
sudo systemctl stop caddy
sudo certbot certonly --standalone -d api.example.com
sudo systemctl start caddy

Check The Certificate

1
2
3
4
sudo certbot certificates
sudo openssl x509 \
-in /etc/letsencrypt/live/api.example.com/fullchain.pem \
-noout -dates

Enable Renewal

1
2
sudo systemctl enable --now certbot.timer
systemctl list-timers | grep certbot

Run a dry test:

1
sudo certbot renew --dry-run

Deploy Hook

Some services cannot read directly from /etc/letsencrypt/live/..., or they need certificate files copied into a service-owned directory.

Example hook for a service called myapp:

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env bash
set -euo pipefail

DOMAIN="api.example.com"
TARGET_DIR="/etc/myapp/cert"

install -d -m 0750 "$TARGET_DIR"
install -m 0644 "/etc/letsencrypt/live/$DOMAIN/fullchain.pem" "$TARGET_DIR/fullchain.pem"
install -m 0600 "/etc/letsencrypt/live/$DOMAIN/privkey.pem" "$TARGET_DIR/privkey.pem"

systemctl reload myapp

Install it as a deploy hook:

1
2
sudo install -m 0755 deploy-myapp-cert.sh \
/etc/letsencrypt/renewal-hooks/deploy/myapp.sh