The committed dist was stale (older build without email-resolving + username login).
Rebuild locally and commit the fresh SPA so EasyPanel serves the correct login/setup
flow. Verified fresh dist references username/must_setup/setup.
Root cause of 'wrong password' right after logout->login (no redeploy): after first-run
setup sets an email, users naturally type their EMAIL in the login field, but verify()
only looked up by USERNAME -> user not found -> 'invalid credentials' shown as wrong
password. Now verify(ident) = get_user_or_none(username) OR by_email(ident). Verified:
login by username (200) and by email (200) both work with the new password.
Tests: m0/setup/e2e all pass.
Root cause of re-login failing after first-run setup: on EasyPanel/w/o a volume, the
container's /app/backend/data (users, incl. the changed admin password) is wiped on every
recreate, so logging back in with the new password fails. Added:
- ENV DATA_DIR=/app/backend/data (explicit) + VOLUME declaration in Dockerfile
- README 'Data persistence' section: must mount a persistent volume to /app/backend/data
Verified: backend + live server login>setup>relogin-with-new-password works (200); the
failure is deployment data persistence, not login logic.
The Vue SPA is now built locally and its frontend/dist/ committed (force-added).
Dockerfile is a single-stage runtime: copy prebuilt dist + python:3.11 + Flask.
No node/npm inside the image -> deterministic, no npm/esbuild postinstall flakiness.
To update UI: edit src, npm run build, commit frontend/dist/.