Files

1.5 KiB

Static File Caching — Ops Portal

Pitfall (Jul 10, 2026): The ops portal serves static HTML/JS/CSS through FastAPI's FileResponse. Without explicit Cache-Control headers, browsers aggressively cache these files. After editing app.js, servers.html, or ops.css, users see stale versions — even after hard refresh. The login page, server health, and API calls all appear broken because the browser is serving cached JavaScript.

Symptoms:

  • User reports "pages won't refresh" despite confirmed deploys
  • curl returns HTTP 200 with correct content, but browser shows old version
  • JS changes (401 redirect fix, new endpoint calls) don't take effect
  • User has to manually Ctrl+Shift+R every page

Fix: Add Cache-Control: no-cache, no-store, must-revalidate headers to all FileResponse calls in server.py:

return FileResponse(str(fpath), headers={"Cache-Control": "no-cache, no-store, must-revalidate"})

This applies to HTML pages, CSS, and JS. After adding headers, restart the service:

systemctl restart ops-portal

Why this matters for ops: The portal uses vanilla HTML/JS with no framework, no bundler, and no cache-busting hashes. Every file edit requires either a cache-control header or manual browser refresh. The header approach is reliable across all users.

Files affected:

  • /opt/ops-portal/server.pyserve_css(), serve_js(), serve_index(), serve_html_page()
  • Any @app.get("/{page}.html") handler