node:20-alpine uses BusyBox which does not support GNU-style
--system/--ingroup flags. Switch to -S/-G equivalents.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Both backend and frontend Dockerfiles ran all processes as root.
Add a dedicated appuser in each runtime stage so container processes
run with minimal privileges, limiting blast radius of any container
escape.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>