From 021bd043243d980d27582ced36c13a7834bc7771 Mon Sep 17 00:00:00 2001 From: Stephan D Date: Sun, 18 Oct 2026 13:54:30 +0200 Subject: [PATCH] Reap orphaned frontend HTTPS probe processes (#57) --- docs/local-development.md | 7 +++++++ docs/signup-facts.md | 18 ++++++++++++++++++ infra/local/compose.yml | 2 ++ 3 files changed, 27 insertions(+) diff --git a/docs/local-development.md b/docs/local-development.md index 5cef411..9a45573 100644 --- a/docs/local-development.md +++ b/docs/local-development.md @@ -27,6 +27,13 @@ project directory. Dockerfiles are in `infra/images/`. Runtime and startup files are grouped by service under `infra/local/`. The stack consists of Vault, Mongo, NATS, notifications, BFF and Caddy serving the frontend. +The frontend container uses Compose `init: true` to reap orphaned `ssl_client` +children created by BusyBox's HTTPS `wget` health probe. Keep this enabled: +Caddy alone does not reap those children when it runs as PID 1, and repeated +probes can accumulate thousands of zombie processes. Recreate the frontend +container when applying this setting; restarting an old container does not +change its init configuration. + On first startup, bootstrap initializes/unseals persistent Vault, provisions AppRoles and secrets, initializes Mongo replica set `rs0`, configures Vault's Mongo plugin, and starts authenticated NATS JetStream. Product startup fails explicitly diff --git a/docs/signup-facts.md b/docs/signup-facts.md index 1897e5c..48927cc 100644 --- a/docs/signup-facts.md +++ b/docs/signup-facts.md @@ -144,6 +144,24 @@ BFF to restore Docker DNS and the loopback bridge. Final for frontend/proxied BFF, authenticated Sendico currency/ledger reads and the Vault/database checks. No Sendico repository files were changed. +On October 18, the frontend had 15,897 processes, including 15,888 unreaped +`ssl_client` zombie children of Caddy PID 1. The three-second HTTPS health +probe used BusyBox `wget`, which left those children behind. This confirmed a +recurring local infrastructure leak, independently of SMTP authentication. +Compose now enables `init: true` for frontend, and only that container was +recreated. PID 1 is now `docker-init`; 40 consecutive HTTPS probes completed +with zero zombie processes and a bounded count of 15 processes afterward. +Compose configuration validation and `make test-dev-tooling` pass. The API +health endpoint returns HTTP 200; a diagnostic request using the existing +account and a generated incorrect password returned HTTP 400 `email_in_use` +without creating an account or sending email. + +The contemporaneous full local verification attempt is blocked by MongoDB's +five-second health-check timeout under continuing host load; it is not recorded +as passing. The exact response to the reported Safari attempt was not captured, +and the frontend's generic unavailable text also covers some HTTP 400 input +errors. A fresh user retry is needed to confirm the visible signup outcome. + With `api.sendico` configured, the product BFF creates the local pending customer and activation token atomically, then registers an independent individual through diff --git a/infra/local/compose.yml b/infra/local/compose.yml index a7bb6d3..4377f84 100644 --- a/infra/local/compose.yml +++ b/infra/local/compose.yml @@ -119,6 +119,8 @@ services: frontend: image: sxchnge-local/frontend:dev + # Reap orphaned ssl_client children from BusyBox wget HTTPS health probes. + init: true build: context: . dockerfile: infra/images/frontend.Dockerfile