Certplane’s agent can run a shell command immediately after writing a renewed certificate to disk. Use this to reload your web server, proxy, or any service that reads certificates at startup or on SIGHUP — no cron jobs or external watchers required.
How it works
Each entry in the certificates list in agent.yml accepts two reload-related fields:
reload_command — a shell command string executed after the certificate files are written. The agent passes this directly to /bin/sh -c, so you can use pipes, conditionals, or any other shell syntax.
reload_timeout — how long the agent waits for the command to exit before killing it and logging a timeout error. Accepts Go duration strings such as 30s or 2m.
The reload_command runs as the same operating system user as the agent process. Make sure that user has permission to run the command — for example, by adding a sudoers entry or by granting the agent user membership in the appropriate systemd unit’s ExecReload policy.
If reload_command exits with a non-zero status, the agent logs an error but the certificate is still written to disk. A failed reload does not roll back the certificate or block future renewals.
If reload_timeout is exceeded, the agent kills the reload command and logs an error. Set the timeout long enough for your service’s reload to complete — a value that is too short will leave your service running with the old certificate.
Complete example
The following certificates entry shows all relevant fields together:
certificates:
- name: web-wildcard
profile: public_wildcard
dns_names:
- "*.example.com"
key: /etc/ssl/private/service.key
cert: /etc/ssl/certs/service.crt
chain: /etc/ssl/certs/service.chain.crt
fullchain: /etc/ssl/certs/service.fullchain.crt
reload_command: systemctl reload nginx
reload_timeout: 30s
renew_before: 720h
Examples by service
certificates:
- name: web-wildcard
profile: public_wildcard
key: /etc/ssl/private/service.key
cert: /etc/ssl/certs/service.crt
fullchain: /etc/ssl/certs/service.fullchain.crt
reload_command: systemctl reload nginx
reload_timeout: 30s
certificates:
- name: edge-wildcard
profile: public_wildcard
key: /etc/ssl/private/service.key
cert: /etc/ssl/certs/service.crt
fullchain: /etc/ssl/certs/service.fullchain.crt
reload_command: systemctl reload traefik
reload_timeout: 30s
certificates:
- name: vault-cert
profile: internal_vault
key: /opt/vault/tls/vault.key
cert: /opt/vault/tls/vault.crt
fullchain: /opt/vault/tls/vault-fullchain.crt
reload_command: systemctl reload vault
reload_timeout: 30s
certificates:
- name: lb-wildcard
profile: public_wildcard
key: /etc/haproxy/certs/service.key
cert: /etc/haproxy/certs/service.crt
fullchain: /etc/haproxy/certs/service.fullchain.crt
reload_command: systemctl reload haproxy
reload_timeout: 30s
certificates:
- name: web-wildcard
profile: public_wildcard
key: /etc/ssl/private/service.key
cert: /etc/ssl/certs/service.crt
fullchain: /etc/ssl/certs/service.fullchain.crt
reload_command: /usr/local/bin/deploy-cert.sh
reload_timeout: 60s
Using a wrapper script for complex logic
If your reload logic involves multiple steps — for example, concatenating the key and certificate into a PEM bundle, setting ownership, and then reloading HAProxy — put that logic in a wrapper script and point reload_command at it. This keeps agent.yml readable and makes the reload logic independently testable.#!/usr/bin/env bash
set -euo pipefail
cat /etc/ssl/private/service.key /etc/ssl/certs/service.fullchain.crt \
> /etc/haproxy/certs/bundle.pem
chown haproxy:haproxy /etc/haproxy/certs/bundle.pem
chmod 640 /etc/haproxy/certs/bundle.pem
systemctl reload haproxy
Make the script executable (chmod +x /usr/local/bin/deploy-cert.sh) and ensure it is owned by root or the agent user.