Fix MEDIUM findings from 2026-09-24 maintenance review
- Backend retries DB connection at startup (up to 180s) so host reboots no longer crash-loop it; add backend and frontend healthchecks - Docker log rotation (json-file 10m x 3) on all services - ntfy alerts use X-Real-IP (set by nginx after real_ip resolution) instead of the client-controlled first X-Forwarded-For entry - Frontend build on Node 24 LTS with package-lock.json + npm ci; axios 1.20.0, vite 5.4.21 - README: backup/restore/rollback runbook, real-IP proxy trust notes - Release-Notes/v1.1.md; version 1.1.0 Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
3170c7f4eb
commit
4130467b22
11 files changed
+1851
-20
No files matched your search
@@ -134,7 +134,7 @@ This section was first blocked on backups. The user then asked for the HIGH find
|
||||
| Real-IP rate limiting tested | PASS | Test nginx: client A was limited after its burst, client B was unaffected, and a forged XFF prefix resolved to the true client. |
|
||||
| Deploy | PASS* | The MySQL data upgrade (80040 → 80411) took about 90s, longer than the healthcheck window, so compose aborted the dependent containers. The user started them manually. Fixed by adding `start_period: 180s` to the db healthcheck. |
|
||||
| Sections 2/3 re-run | PASS (partial) | All containers up, backend logs clean, public `/api/health` 200. Live bundle now contains `8e92ae6`. nginx logs real client IPs. The user confirmed the site is back up. |
|
||||
| Version tag / release notes | DEFERRED | The repo has no tagging or `Release-Notes/` convention yet. |
|
||||
| Version tag / release notes | PASS | `v1.1.0`, `Release-Notes/v1.1.md` |
|
||||
| Old images cleanup | DEFERRED | Keep the rollback tags and volume copy until the update has been stable for about a week. Then remove them: `docker rmi homeschool-{backend,frontend}:rollback-20260924 mysql:8.0.40` and `docker volume rm homeschool_mysql_data_pre84_20260924`. |
|
||||
|
||||
### Changes applied
|
||||
@@ -184,13 +184,13 @@ This section was first blocked on backups. The user then asked for the HIGH find
|
||||
3. ~~Fixable HIGH/CRITICAL CVEs in all images and Python deps.~~ Fixed by the rebuild and dependency bumps.
|
||||
4. ~~MySQL 8.0 is EOL.~~ Upgraded to 8.4.11 LTS.
|
||||
|
||||
### MEDIUM
|
||||
### MEDIUM (all resolved 2026-09-24, v1.1.0)
|
||||
5. ~~The frontend is not deployed at HEAD.~~ Resolved by the rebuild.
|
||||
6. No Docker log rotation.
|
||||
7. The backend crash-loops on every host reboot (DB startup race). The db `start_period` does **not** fix this: on reboot, Docker's restart policy ignores `depends_on`. It needs connect-retry in the backend startup. backend and frontend have no healthchecks.
|
||||
8. Node 20 (build stage) is EOL, and there is no `package-lock.json`.
|
||||
9. There is no rollback/restore runbook, and there are no release tags.
|
||||
10. Client IP in ntfy alerts can be spoofed through `X-Forwarded-For`.
|
||||
6. ~~No Docker log rotation.~~ Added `x-logging` anchor (json-file, 10m × 3) to all services.
|
||||
7. ~~The backend crash-loops on reboot, and there are no backend/frontend healthchecks.~~ `_wait_for_db()` in `main.py` retries for up to 180s. Tested: the backend started before its DB, logged retries, and came up with 0 restarts. Healthchecks were added to both services.
|
||||
8. ~~Node 20 EOL and no lockfile.~~ Now node:24.21.0-alpine with `package-lock.json` and `npm ci`. axios → 1.20.0, vite → 5.4.21. Remaining npm audit items (vite ≤6.4.2 / esbuild) are dev-server-only and accepted; the fix needs Vite 6.4+.
|
||||
9. ~~No rollback/restore runbook or release tags.~~ README now has "Backup, Restore & Rollback" and documents real-IP proxy trust. Added `Release-Notes/v1.1.md` and tagged `v1.1.0`.
|
||||
10. ~~Client IP in ntfy alerts can be spoofed.~~ New `app/utils/client_ip.py` reads `X-Real-IP`, which nginx sets after real_ip resolution. Tested: a forged XFF is ignored.
|
||||
|
||||
### LOW
|
||||
11. db memory is at 82% of its 512 MiB limit.
|
||||
@@ -208,7 +208,7 @@ Portainer/NPM drift, functional smoke tests, ntfy test, off-host/VM backups, HTT
|
||||
- Failed (critical/high): 7. That is backups (counted once, CRITICAL), rate limiting, image CVEs, dependency CVEs, runtime EOL, log rotation and frontend drift.
|
||||
- Failed (non-critical) / WARN: 18
|
||||
- Pending user confirmation: 14
|
||||
- Deferred: 2 (release tag, old image cleanup)
|
||||
- Updates applied: 4 (real-IP rate limiting, Python deps, base images, MySQL 8.4)
|
||||
- Deferred: 1 (old image cleanup)
|
||||
- Updates applied: 9 (HIGH: real-IP rate limiting, Python deps, base images, MySQL 8.4. MEDIUM: log rotation, DB-wait + healthchecks, Node 24 + lockfile, runbook + release tag, trusted client IP)
|
||||
|
||||
**Overall: NEEDS ATTENTION.** All HIGH findings are resolved. The CRITICAL no-backups finding is still open: the pre-update dump and volume copy are on-host only, with no schedule.
|
||||
**Overall: NEEDS ATTENTION.** All HIGH and MEDIUM findings are resolved. The CRITICAL no-backups finding is still open: the pre-update dump and volume copy are on-host only, with no schedule.
|
||||
Reference in new issue
Block a user