Files
certbot/docker
bitdeals a842e0771e
Build docker image and push to registry.bitdeals.org / main-build-job (push) Successful in 36s
fix: HAProxy could not read the placeholder, so a failed issuance took the site down
The placeholder is the whole reason a first start works at all: HAProxy
resolves `bind ... ssl crt` while parsing its configuration, so it cannot
start without site.pem, and certbot writes a self-signed one to break
that circle. It wrote it 0600 root-only, under the umask the subshell
sets for the private key it builds it from. HAProxy runs unprivileged
(uid 1001 in the bitnami image), so it could not open the file and exited
-- and because it never came up, it never created the runtime API socket
the pass waits for, and the pass hung in that wait instead of reaching
the 12-hour sleep. A node whose first issuance failed -- a typo in
CERTBOT_DOMAIN is enough -- served nothing at all on 80 or 443, retried
nothing, and said so only in two container logs.

The real certificate escapes this by accident: 2-concatenate-cert.sh
writes it with `cat >` under the default umask, so site.pem is 0644 on
every node that ever issued one. That is why nobody hit this -- it needs
a first issuance that fails.

chmod on the temporary file rather than after the rename, so the atomic
rename stays the only thing HAProxy can observe and site.pem never exists
with a mode that stops it. The intermediates keep the tight umask.

Reproduced on a disposable haproxy+certbot stack with empty volumes and
CERTBOT_DOMAIN=testnet2.bitdeals.invalid: before, HAProxy crash-looped on
"cannot open the file" while certbot waited for admin.sock; after, HAProxy
starts on the placeholder, certbot reports the rejected domain, the loop
retries in 12h, and the site answers on 80 and terminates TLS on 443 with
the self-signed certificate.

Claude-Session: https://claude.ai/code/session_01BvgYcYPWd1KGABLKViVPSk
2026-08-24 13:13:23 +00:00
..