curltastic/docker/README.md
2026-09-08 02:15:45 +00:00

3.7 KiB

Production images

Build from the repository root (no source mounts or runtime package installs):

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.

(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.