fix: OS package upgrades run on every image build, so Trivy stops failing on fixes the cache hid

Merged
HA
15h ago
+8-3

Summary

Docker Scan & Promote has failed on every main commit since at least 7dbe76ff (latest run), so latest stopped moving and the nightly release has found nothing new since 2026.10.27 (bcbf2498, Oct 14). The backend image carries libcurl4t64 8.14.1-2+deb13u5 with three HIGH CVEs (CVE-2026-92392, CVE-2026-8927, CVE-2026-8286) that deb13u7 fixes. The Dockerfile does run apt-get upgrade, but in the base stage, and CI restores that stage from its tarball cache and the GHA layer cache, so the upgrade layer is the one from whenever it was first built.

Changes

The backend upgrades its OS packages in its last stage, which CI builds fresh every run, and the base stage no longer does. The frontend's stage is named production, and CI builds it with no-cache-filters: production, so its apk upgrade can't go stale the same way.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Refactoring (no functional changes)
  • CI/CD or tooling changes

Test Plan

  • Backend unit tests pass (cd backend && uv run pytest tests/unit)
  • Frontend unit tests pass (cd frontend && npm run test)
  • Backend E2E tests pass (docker compose exec -T backend sh -c 'uv sync --group test --no-dev --frozen --no-install-project --no-build && pytest tests/e2e')
  • Frontend E2E tests pass (cd frontend && npm run test:e2e)
  • API spec and client regenerated if routes or schemas changed (./deploy.sh openapi, then ./deploy.sh types), never edited by hand
  • Manual testing performed

Validation: built the backend the CI way on the stale published base:latest (libcurl4t64 deb13u5); the result has deb13u7. The scan itself runs after this merges, in Docker Scan & Promote.

Checklist

  • My code follows the project's style guidelines
  • I have run pre-commit run --all-files and all checks pass
  • I have added tests that prove my fix/feature works
  • I have updated documentation if needed
  • My changes don't introduce new warnings

Summary by cubic

Fixes Docker Scan & Promote failing on every main commit by moving OS package upgrades to build layers CI never caches, so security fixes released after a cached build (like the backend image's libcurl4t64 HIGH CVEs) actually land in the published images.

  • The backend's base stage no longer runs apt-get upgrade; a new step in the final stage, which CI builds fresh every run, does.
  • The frontend's production stage is now named production and CI builds it with no-cache-filters: production, so its apk upgrade can't go stale.
  • Updates docs/security/supply-chain.md to describe the new caching behavior.