Certificate renewal
Manual renewal
Generate with certbot
sudo docker run -it --rm \
-v /etc/letsencrypt:/etc/letsencrypt \
-v /var/lib/letsencrypt:/var/lib/letsencrypt \
certbot/certbot certonly \
--manual --preferred-challenges dns \
-d people-t.com -d '*.people-t.com' \
--agree-tos -m dbeletsis@people-t.com
Certificate is saved at:
/etc/letsencrypt/live/people-t.com/fullchain.pemKey is saved at:
/etc/letsencrypt/live/people-t.com/privkey.pem
Restart WordPress
Choose ONE of the options below.
-
The right way
sudo docker exec wordpress-nginx nginx -tsudo docker exec wordpress-nginx nginx -s reload -
The very manual way
docker compose -f ~/wordpress-root/compose.yml --env-file ~/wordpress-root/.env.wordpress downdocker compose -f ~/wordpress-root/compose.yml --env-file ~/wordpress-root/.env.wordpress up -d-f ~/wordpress-root/compose.yml --env-file ~/wordpress-root/.env.wordpressare required options.
Automatic renewal
Setup
-
Create API token in Cloudflare.
Setting Value Permissions Zone·DNS·EditPermissions Zone·Zone·ReadZone Resources Include·Specific zone·people-t.comObviously, this requires the proper access to the DNS settings of
people-t.com. -
Save it to the machine's environment.
sudo mkdir -p /root/.secretsecho "dns_cloudflare_api_token = <TOKEN>" | sudo tee /root/.secrets/cloudflare.inisudo chmod 600 /root/.secrets/cloudflare.ini
Test run
-
Issue certificate with Cloudflare plugin.
sudo docker run --rm \-v /etc/letsencrypt:/etc/letsencrypt \-v /var/lib/letsencrypt:/var/lib/letsencrypt \-v /root/.secrets:/secrets:ro \certbot/dns-cloudflare certonly \--dns-cloudflare \--dns-cloudflare-credentials /secrets/cloudflare.ini \--dns-cloudflare-propagation-seconds 30 \--cert-name people-t.com \-d people-t.com -d '*.people-t.com' \--agree-tos -m dbeletsis@people-t.com \--force-renewal \--non-interactive -
Confirm change.
sudo grep -E 'authenticator|credentials' /etc/letsencrypt/renewal/people-t.com.confShould print the following:
authenticator = dns-cloudflaredns_cloudflare_credentials = /secrets/cloudflare.ini -
Prove renewal works (Dry-run).
sudo docker run --rm \-v /etc/letsencrypt:/etc/letsencrypt \-v /var/lib/letsencrypt:/var/lib/letsencrypt \-v /root/.secrets:/secrets:ro \certbot/dns-cloudflare renew --dry-runThis will take about 1 minute to execute.
Expected result:
Saving debug log to /var/log/letsencrypt/letsencrypt.log- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Processing /etc/letsencrypt/renewal/people-t.com.conf- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Account registered.Simulating renewal of an existing certificate for people-t.com and *.people-t.comWaiting 30 seconds for DNS changes to propagate- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Congratulations, all simulated renewals succeeded:/etc/letsencrypt/live/people-t.com/fullchain.pem (success)- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Actual run and Cron
We have pre-created a script in
/usr/local/bin/renew-certs.sh.
-
Give permissions to execute script.
sudo chmod 700 /usr/local/bin/renew-certs.sh -
Run manually to test.
sudo /usr/local/bin/renew-certs.shExpect
valid 89 more daysand exit 0. -
Schedule it.
sudo crontab -eMAILTO="dbeletsis@people-t.com,sdermanoutsos@people-t.com"17 3,15 * * * /usr/local/bin/renew-certs.sh >> /var/log/certbot-renew.log 2>&1 -
Verify what's actually served.
echo | openssl s_client -connect people-t.com:443 -servername people-t.com 2>/dev/null \| openssl x509 -noout -dates -subject -ext subjectAltNameExpected output:
notBefore=Jul 28 06:37:40 2026 GMTnotAfter=Oct 26 06:37:39 2026 GMTsubject=CN = people-t.comX509v3 Subject Alternative Name:DNS:*.people-t.com, DNS:people-t.com -
Confirm that cron job runs properly.
sudo env -i PATH=/usr/bin:/bin HOME=/root /usr/local/bin/renew-certs.shThis also confirms it runs from its own environment instead of our shell.