hello-web/README.md
nholtware 444044b99a
All checks were successful
/ checks (push) Successful in 38s
/ deploy (push) Successful in 4s
feat: JSON access log in the platform logging contract
2026-11-05 10:54:12 -06:00

51 lines
2.1 KiB
Markdown

# hello-web
Test frontend for `hello-svc`. Frontend service generated from `nholtware/service-template-react`: a Vite +
React 19 + React Router (data mode) SPA, served as static files by
unprivileged nginx.
## Develop
```sh
npm install
npm run dev # http://localhost:5173, /api proxied to API_PROXY_TARGET (default http://localhost:3000)
npm test
npm run lint
npm run format
```
## Runtime config
`/config.js` sets `window.__APP_CONFIG__`. In the container,
`docker-entrypoint.d/10-config.sh` writes it at start from env vars, so one
image runs in every environment. Read values through `getConfig()` in
`src/lib/config.ts`.
| Env var | Default | Meaning |
| -------------- | ------- | ----------------------------------------------- |
| `API_BASE_URL` | `/api` | Backend base URL; `/api` is the same-host route |
| `APP_NAME` | `app` | Display name |
Everything in `config.js` is public. Never put secrets there.
## Container
- `GIT_SHA` build arg is baked in as `import.meta.env.VITE_GIT_SHA`.
- nginx listens on 8080: `/healthz` returns 200, unknown paths fall back to
`index.html`, `/assets/*` are cached as immutable, and `index.html` and
`config.js` are not cached.
- Access log: one JSON line per request in the platform logging contract
(`level`, `time`, `service` = `APP_NAME`, `version` = `GIT_SHA`, `req.id`
(echoes `X-Request-Id`), `req.method`, `req.url`, `res.statusCode`,
`responseTime` in ms, `msg: "request completed"`), the same shape as the backend
template. In Kibana (http://kibana.192.168.1.83.nip.io, data view `kube-*`):
`service:"hello-web" and res.statusCode >= 400`. `/healthz` isn't logged.
nginx's own startup/error lines stay plain text (field `log`).
## Deploy
Push to `main`: Forgejo CI runs lint/test/format, builds and pushes
`192.168.1.230:3000/nholtware/hello-web:<sha>`, and bumps the tag in the
gitops repo. ArgoCD then syncs it. Manifests come from gitops
`templates/frontend/`. The repo needs Actions secrets `REGISTRY_USER`,
`REGISTRY_TOKEN`, and `GITOPS_TOKEN`.