Features
Certificates That Renew Themselves
Automatic TLS, what breaks renewal, and how to notice before it expires.
7 October 2026

How Caddy Manages the Lifecycle
Caddy terminates TLS for every site on the stack, including the four domains served by the Next.js process and the separate Node instance for Instalaz. It requests certificates from Let's Encrypt automatically, storing them in a local directory. The system checks expiration dates and triggers renewal roughly thirty days before a certificate lapses. This runs in the background, independent of the application code. The static builds for GamingCap and Invoiceful are served directly from disk by Caddy, so they benefit from the same automated protection without running their own web servers. Because there is only one PostgreSQL database shared by the dynamic apps, the certificate management remains centralised rather than fragmented across multiple services.
The reliance on this automation means the failure modes are specific. If Caddy cannot validate domain ownership, it will not renew. The most common cause is a DNS misconfiguration. Since DNS is managed at Spaceship, any change to A records or CNAMEs that points the domain away from the VPS IP address will break the ACME challenge. The server needs to be reachable on port 80 for the HTTP-01 validation. If a firewall rule blocks port 80, or if another process is already bound to it, the renewal request times out. The certificate remains valid until its expiration date, but the renewal cycle is broken.
Why Renewal Fails
Processes on one box compete for resources, but certificate renewal is primarily a network and DNS issue. The Let's Encrypt client inside Caddy must perform a handshake that proves control of the domain. If the DNS TTL is high, propagation delays can cause the initial validation to fail. However, once a certificate is issued, renewal failures are usually due to infrastructure changes. Moving the VPS, changing the IP address, or updating DNS records without ensuring the new IP is reachable will stop renewals. The system does not alert you proactively; it simply stops updating the certificate files.

Monitoring Expiry Without Alerts
Because the renewal is automatic, it is easy to assume it is working. To verify, you can check the certificate expiry date directly using standard command-line tools. Running a command to inspect the certificate for a specific domain shows the not-after date. If this date is approaching and the certificate has not updated, the renewal process is broken. You can also check the Caddy logs for ACME errors. These logs will contain specific error codes from Let's Encrypt, such as rate limit errors or validation failures. Watching these logs is more reliable than waiting for a browser to throw a security warning.
Preventing Silent Failures
The best defence is ensuring that DNS records are stable and that port 80 is open. If you change DNS providers or update records, test the ACME challenge immediately. You can force a renewal by deleting the existing certificate directory and restarting Caddy. This triggers a new issuance attempt. If this fails, the error message in the logs will point to the specific issue. For static sites like the Invoiceful generator, the impact of an expired certificate is immediate: browsers will block access entirely. For the dynamic apps, the result is the same. Keeping the ACME client healthy is a matter of regular log inspection and DNS hygiene, not complex monitoring software.


