The frontend container was serving the very first build (498-byte index.html) through every later deploy: `docker compose up -d` did not replace a config-identical service. Deploy now uses `build --pull` and `up --force-recreate`, the frontend image writes a .build-version marker, and the workflow fails the deploy if the served marker != the commit SHA.