Branch: refs/heads/master Home: https://github.com/phpmyadmin/scripts Commit: 5a131dc67dec2d1d269bff055b53eb220c4344ae https://github.com/phpmyadmin/scripts/commit/5a131dc67dec2d1d269bff055b53eb2... Author: William Desportes <williamdes@wdes.fr> Date: 2026-11-09 (Mon, 11 November 2026) +01:00 Changed paths: M infrastructure/sentry/.env.dist M infrastructure/sentry/README.md M infrastructure/sentry/compose.yml Log Message: ----------- sentry: replace Sentry 9.1.2 with a hardened error tracking stack Sentry 9.1.2 is EOL and needs redis, a cron container and a worker for what is now one process. Replace the stack with a Sentry-SDK-compatible server on PostgreSQL: the API, the dashboard and ingest all served by it. No data is imported. The new server speaks the Sentry ingestion protocol, not the Sentry schema, and the old cluster is PostgreSQL 13, so the new instance starts empty and the old data directories are left untouched. Networking, verified on a running stack: every network is a plain bridge, and all but `egress` disable masquerading, so outbound packets keep their private source address and nothing answers. `egress` is the only network with NAT and `smtp` is its only member. One mechanism, one comment, no mix of `internal: true` and bridge options. `postgres` and `sentry` additionally set `dns: 127.0.0.1`, which stops Docker's resolver forwarding external names upstream; peer names still resolve. That is what completes the sealed networks, which stop TCP but not DNS lookups. The relay keeps the default resolver, since MX lookups need it. The trade-off is in the README: a sealed container keeps a default route to the host and is dropped for want of NAT, where `internal: true` has no route at all. The rest of the hardening: rootless Docker, non-root users, cap_drop ALL, no-new-privileges, read-only rootfs with noexec/nosuid tmpfs, mem/cpu/pids limits. Postgres keeps no capability either: the bind mount is pre-chowned by a one-shot `init` profile instead of adding chown/fowner/dac_override. Telemetry, DO_NOT_TRACK and metrics off, so /metrics is 404. Images pinned by digest, each with its tag and date. The exim relay stays for alert and invitation email, now on the sealed network with SMTP_HOST=smtp. Its queue is a tmpfs, so a message queued while delivery fails does not survive a restart. The HELO name the old compose file hardcoded is now SMTP_HELO_HOSTNAME, so no hostname is written in any committed file. The .env keys keep the names the Sentry stack used: keep POSTGRES_PASSWORD as it is, regenerate SENTRY_SECRET_KEY (refused below 64 bytes, and the old one was 40), repoint the two data paths at empty directories, and add PUBLIC_URL, SMTP_HELO_HOSTNAME and SENTRY_SERVER_EMAIL. Those three are required, with no default, so compose refuses to start rather than build DSNs, HELOs and senders out of a placeholder. The binary's SSL_PROXY reads as a TLS switch but only sets the session cookie's Secure flag, besides making the secret mandatory, so the .env key is COOKIE_SESSION_SECURE and compose maps it to SSL_PROXY. Verified both ways: the cookie carries Secure only when the key is true. Nothing in the server reads X-Forwarded-Proto, so the proxy header is for logs. Signed-off-by: William Desportes <williamdes@wdes.fr> Co-Authored-By: DeepSeek <noreply@deepseek.com>