Repository navigation
Containerized stack: production frontend service in docker-compose.test.yml - #83
Merged
Merged
Conversation
frontend/Dockerfile builds the SPA in a node stage and serves it with nginx, which proxies /api (REST + game WebSocket) and /health to $BACKEND_URL like the Vite dev proxy, with SPA fallback for client-side routes and a healthcheck. The compose service sits behind the "frontend" profile so make test-integration never builds it; make test-frontend-container runs tests/frontend_proxy/ against it.
Owner
Author
|
Independent review: PASS
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Card W3-10 (part of issue
containerized-stack).Starting point
On main (2f79530),
docker-compose.test.ymlhad onlybackendandintegration-tests. The web UI could only run through the Vite dev server. This item was still open on main.Change
frontend/Dockerfile: multi-stage build. Anode:22-alpinestage runsnpm ci && npm run build, which includestsc -b. Annginx:1.27-alpinestage servesdist/. The image has aHEALTHCHECK.frontend/nginx.conf.template: rendered at start-up by the nginx image's envsubst step. Only${BACKEND_URL}is substituted (defaulthttp://backend:8001). It mirrorsvite.config.ts:/api/is proxied to the backend with WebSocket upgrade headers (Upgrade/Connectionmap, HTTP/1.1).Hostis preserved, like Vite's defaultchangeOrigin: false. Read/send timeouts are 1h so idle game sockets stay open.= /healthis proxied./usestry_files … /index.html, soBrowserRouterdeep links work./assets/returns 404 for missing files instead of serving the SPA shell, and caches hashed bundles as immutable.docker-compose.test.ymladds two services, both behindprofiles: ["frontend"]:frontend: healthcheck,depends_on: backend (service_healthy), published on${FRONTEND_PORT:-8080}.frontend-smoke: reuses theDockerfile.testimage and mountstests/frontend_proxy/.Because of the profile,
docker compose config --serviceswithout it is stillbackend, integration-tests.make test-integrationdoes not build or start the frontend and is no slower.make test-frontend-container(new, separate target): brings up backend, frontend and frontend-smoke. The exit code comes fromfrontend-smoke. It then runsdown..dockerignore: the root file (backend context) gets a comment that it already excludesfrontend/. A newfrontend/.dockerignoreexcludesnode_modules,distand editor files.Docs: README gets a "Containerized stack" subsection, plus updated requirements and the command list. CLAUDE.md gets the command list and a log-to-file example.
Tests
tests/frontend_proxy/test_frontend_proxy.pyhas 9 tests, all going through the nginx container:/src/main.tsx/master/healthis proxied/api/master/worldsreturns the same result through the proxy as from the backend directlyturnis received andend_turnis sentThese are outside
testpaths, somake testdoes not pick them up.Fails on main: yes. With main's compose file,
docker compose --profile frontend up … frontend frontend-smokefails withno such service: frontend, and main has notest-frontend-containertarget.What was run
make check: green. 2939 pytest, 353 vitest, ruff, mypy, eslint and tsc all pass.make test-integrationwith the new compose file: 184 passed, and no frontend container started.docker compose configis valid with and without the profile.Not run as-is: the literal
make test-frontend-container/make test-integrationwith--build. In the dev VM,ghcr.ioblobs (theuvimage) are blocked. Containers also can't reach PyPI or npm without the sandbox's proxy CA. I built the three images locally with--network hostand the proxy CA injected through a scratch copy of each Dockerfile; the repo Dockerfiles were not changed. I then ran the same compose services with--no-build. The build steps themselves, includingnpm ciandnpm run buildin the node stage, succeeded that way.Found, not fixed (out of scope)
make test-integrationnever runsdocker compose down, so containers and the network are left behind between runs. The new target does clean up.${UID:-1000}. IfUID/GIDaren't exported (for example when callingdocker composedirectly from bash, whereUIDis a non-exported shell variable), the backend can't createsaves/<world>in a root-owned./saves, and autosave logsPermissionError. This is not fatal to the tests.DND_DICE_SEED=42. A production compose file using the realcontent/, persisted saves and no fixed seed would be a separate item.frontend/ordocker*, is a follow-up decision.