- Frontend on nginx-unprivileged (non-root, container port 8080) - Replace unmaintained passlib with bcrypt 5.0.0 (hash-compatible) - Pass DOCS_ENABLED through to the backend container - Raise db mem_limit to 768m for MySQL 8.4 Co-Authored-By: Claude Opus 5.5 <[email protected]>
2.9 KiB
2.9 KiB
v1.1
v1.1.0 — 2026-09-24
Maintenance release from the 2026-09-24 review (reports/maintenance-2026-09-24.md).
Security
- Rate limits now apply to each client. nginx resolves the real client IP through Cloudflare → NPM (
set_real_ip_from+real_ip_recursive). Before this, every request looked like it came from NPM, so all users shared one login limit. - ntfy alerts show the real client IP (
X-Real-IPfrom nginx). They no longer use the firstX-Forwarded-Forentry, which the client controls. - Python dependency updates (pydantic now pinned at 2.13.5):
- PyJWT 2.15.0 (fixes an auth bypass)
- anyio 4.15.1
- fastapi 0.141.1 / starlette 1.7.0
- cryptography 50.0.1
- python-multipart 0.0.32
- alembic 1.20.0 / Mako 1.4.3
- Base images:
- python 3.12.14-slim, with
apt-get upgradeand without the unused gcc/mysqlclient headers - nginx 1.30.5-alpine (stable), with
apk upgrade - Node 24 LTS for the build stage
- python 3.12.14-slim, with
- axios 1.20.0 and vite 5.4.21. Frontend dependencies are now locked in
package-lock.jsonand installed withnpm ci.
Platform
- MySQL 8.0.40 (EOL) → 8.4.11 LTS. The data dictionary is upgraded in place, and you can't downgrade in place. Restore the pre-upgrade volume copy or dump instead; see README "Backup, Restore & Rollback".
Reliability
- The backend retries the DB connection for up to 180s at startup. Before this it crash-looped after host reboots, because the restart policy ignores
depends_on. - Healthchecks on backend (
/api/health) and frontend. The db healthcheck hasstart_period: 180s. - Docker log rotation on all services: json-file, 10 MB × 3.
Fixes
- Timer actions returned 500 after the FastAPI 0.141 upgrade. The session queries didn't load
Subject.options, whichDailySessionOutserializes. Old FastAPI silently swallowed the failed lazy-load; the new one raises it. Now eager-loaded insessions.py(get/timer) anddashboard.py. - The meeting alert catch-up window fix (
8e92ae6) is now deployed.
Known / accepted
- npm audit: vite ≤6.4.2 and esbuild advisories affect only the dev server, which production never runs (it serves the static build). Fixing them fully needs Vite 6.4+/7.
- mysql:8.4.11 has upstream findings in Oracle's image: curl, bundled Python tools, and gosu's Go stdlib.
v1.1.1 — 2026-09-25
Low-severity items from the 2026-09-24 review.
- Frontend runs as non-root:
nginxinc/nginx-unprivileged:1.30.5-alpine, listening on 8080 in the container. Host port 8054 is unchanged, so NPM needs no change. - Replaced unmaintained
passlibwithbcrypt5.0.0 directly. Existing$2b$hashes still verify; passwords are truncated to 72 bytes as before. A malformed hash now fails verification instead of raising. DOCS_ENABLEDis now passed to the backend container (defaultfalse), so the README instructions work.- db
mem_limit512m → 768m (MySQL 8.4 was at ~86% of 512m).