Vite's dev server is the whole app here — it serves the client and runs every
API proxy as middleware — so one container running `npm run dev` covers it, and
HOST/PORT are already env-driven.
Three details are deliberate:
- The port publishes to 127.0.0.1. Docker's usual "4173:4173" binds every host
interface, which would silently make the README's LAN warning the default for
a server that brokers configured provider keys.
- The repo is bind-mounted, so keys saved from Provider Settings, .gev-cache
and .gev-logs persist on the host exactly as they do under `npm run dev`.
node_modules stays in the image so a host install cannot shadow the
Linux-built native deps.
- The container runs as the host user, since everything it writes lands in
that bind mount. Vite's dep optimizer still needs to write inside the image's
node_modules, hence the two loosened directories.
Puppeteer's Chromium download is skipped: it is only needed by `npm run
test:track`, which the README points at the host.
Co-Authored-By: Claude Opus 5 <[email protected]>