forked from eros/curltastic
71 lines
3.7 KiB
Markdown
71 lines
3.7 KiB
Markdown
# Production images
|
|
|
|
Build from the repository root (no source mounts or runtime package installs):
|
|
|
|
```sh
|
|
docker build --target frontend -t curltastic-frontend .
|
|
docker build --target backend -t curltastic-backend .
|
|
```
|
|
|
|
| Target | Listener | Runtime user | Healthcheck |
|
|
| --- | --- | --- | --- |
|
|
| `frontend` (default final target) | HTTP `8080` | `101:101` | `GET /healthz` |
|
|
| `backend` | HTTP/WebSocket `3000` | `10001:10001` | `GET /` |
|
|
|
|
The frontend build argument `VITE_BASE_PATH` defaults to `/curltastic/` and is
|
|
passed to `vite build --base`. There are no required runtime environment
|
|
variables, credentials, writable application directories, or persistent volumes.
|
|
The Rust server keeps rooms in memory; rebuilding/restarting it loses games.
|
|
|
|
## Compose integration contract
|
|
|
|
- Publish/route only frontend port **8080**. Explicitly set Traefik's load-balancer
|
|
port to 8080; do not infer it from the upstream nginx image metadata.
|
|
- Traefik routes `/curltastic/` and strips `/curltastic` before forwarding.
|
|
- Attach frontend to Traefik's external `web` network and a private application
|
|
network. Put backend only on that private network, with the service/DNS name
|
|
**`curltastic-backend`**. Do not publish backend port 3000 or enable Traefik on it.
|
|
- The browser requests public `/curltastic/ws` using its existing host, port and
|
|
TLS scheme. nginx receives `/ws` and proxies the upgrade and query string to
|
|
`curltastic-backend:3000/ws`. It also proxies `POST /room`, exposed publicly as
|
|
`/curltastic/room`. The current frontend creates room IDs locally and does not
|
|
make HTTP room requests; there is no separate frontend HTTP API URL to set.
|
|
- Docker DNS is re-resolved every five seconds so backend replacement during
|
|
Compose watch does not leave nginx using a stale container address.
|
|
- Recommended runtime settings: `read_only: true`, `cap_drop: [ALL]`,
|
|
`security_opt: [no-new-privileges:true]`. Give frontend a writable `/tmp` tmpfs
|
|
(mode 1777) for nginx PID/temp files. Backend needs no writable mount.
|
|
- Never mount source code, a Docker socket, or host credentials. The build context
|
|
is allowlisted by `.dockerignore`; host dependencies and `.env*` are excluded.
|
|
- Use Compose watch `action: rebuild`: frontend changes rebuild the `frontend`
|
|
target, backend changes rebuild the `backend` target. Ignore node_modules,
|
|
dist, target, .git and other generated files. Watch Dockerfile for both services
|
|
and `docker/nginx.conf` for frontend.
|
|
|
|
The nginx listener expects already-stripped paths; a raw host-port request to
|
|
`/curltastic/` does not simulate Traefik. Test the public route through a
|
|
prefix-stripping test proxy, or request `/`, `/assets/...`, `/ws`, `/room` directly
|
|
when testing nginx alone.
|
|
|
|
## Development and verification
|
|
|
|
Local `npm run dev` still defaults to `/` and connects to the page hostname on
|
|
backend port 3000. Existing `VITE_WS_URL` overrides are preserved for custom local
|
|
setups; Vite variables are build-time settings, not runtime container settings.
|
|
Room navigation and share links retain the page path.
|
|
|
|
```sh
|
|
(cd frontend && npm ci && npm test -- --pool=forks --poolOptions.forks.singleFork)
|
|
(cd frontend && npm run build -- --base=/curltastic/)
|
|
(cd backend && cargo test --locked)
|
|
```
|
|
|
|
The frontend Docker build runs its tests and TypeScript checking before producing
|
|
static assets. The backend build uses the committed Cargo lockfile.
|
|
|
|
Verification at implementation: frontend 26 tests passed, Rust 22 tests passed,
|
|
and the production subpath frontend build passed. Both Docker build attempts were
|
|
denied by the execution approval layer; image builds, nginx syntax, and live
|
|
HTTP/WebSocket proxy behavior therefore remain unverified. No servers were
|
|
started and no deployment was performed.
|