Skip to content

fix(docker): install jsonschema and copy schemas/ into the image - #134

Merged
dmccoystephenson merged 1 commit into
mainfrom
fix/dockerfile-missing-runtime-deps
Aug 1, 2026
Merged

fix(docker): install jsonschema and copy schemas/ into the image#134
dmccoystephenson merged 1 commit into
mainfrom
fix/dockerfile-missing-runtime-deps

Conversation

@dmccoystephenson

Copy link
Copy Markdown
Member

The image never ran

The Dockerfile (added in #113 for containerized deployment) installs no dependencies, on the stated premise that the game is stdlib-only. That premise is false — src/fishE.py imports jsonschema at module scope, so the game cannot start without it:

  • src/fishE.py:3from jsonschema.exceptions import ValidationError
  • src/validation/schemaValidator.py:4from jsonschema import validate

This was caught when the image was deployed for real for the first time (behind fishe.danielstephenson.dev). The container crash-looped 638 times before it was pulled:

File "/app/examples/../src/fishE.py", line 3, in <module>
  from jsonschema.exceptions import ValidationError
ModuleNotFoundError: No module named 'jsonschema'

The dependency was recorded in exactly one place — .github/workflows/test.yml's pip install pytest pytest-cov jsonschema pygame. There's no requirements.txt, and run.sh's checkDependencies() (which would have installed one) is commented out, so nothing propagated it to the image.

A second, latent bug behind the first

Fixing only the import would have moved the failure rather than removed it. The save-file readers resolve their schemas relative to the process cwd:

PLAYER_SCHEMA_PATH = "schemas/player.json"   # playerJsonReaderWriter.py:5

cwd is /app in the image, and schemas/ was never copied in — so every save load/write would have raised FileNotFoundError. The app would have started, served the menu, and then broken the moment a player touched a save slot.

Changes

  • requirements.txt (new) — jsonschema>=4.0,<5.0. pygame is deliberately excluded: the pygame front-end imports it lazily, so the console and web front-ends run without it.
  • Dockerfile — install from requirements.txt, copy schemas/, and drop the inaccurate "no third-party deps" comment.

Verification

Reproduced and fixed against the exact file layout each Dockerfile produces, using a clean venv with no jsonschema:

old layout fixed layout
python3 examples/web_app.py ModuleNotFoundError: No module named 'jsonschema' starts, serves in ~1s
GET / 200, contains <title>FishE</title>
GET /state 200, JSON with screen/version
validate_against_schema({}, PLAYER_SCHEMA_PATH) FileNotFoundError: schemas/player.json schema loads (raises ValidationError, as expected for {})

The GET / check is the exact command the gateway healthcheck runs.

No src/ changes, so the existing test suite is unaffected — CI installs jsonschema explicitly and is independent of the new requirements.txt.

The image could not start. `src/fishE.py` imports jsonschema at module
scope, but the Dockerfile installed nothing, on the stated premise that
the game is stdlib-only. It isn't:

  src/fishE.py:3                    from jsonschema.exceptions import ValidationError
  src/validation/schemaValidator.py:4  from jsonschema import validate

There is no requirements.txt, and run.sh's checkDependencies() (which
would have installed one) is commented out -- so .github/workflows/test.yml's
`pip install pytest pytest-cov jsonschema pygame` was the only place the
dependency was recorded, and the image never picked it up.

A second, latent bug behind the first: the save-file readers resolve their
schemas relative to the process cwd (PLAYER_SCHEMA_PATH = "schemas/player.json",
cwd = /app in the image), but schemas/ was never copied in -- so every save
load/write would have raised FileNotFoundError even once the import worked.

Adds requirements.txt (jsonschema only; pygame stays out, since the pygame
front-end imports it lazily and neither the console nor web front-end needs
it), installs it in the image, and copies schemas/.

Verified by reproducing the exact production traceback in a clean venv
against the old layout, then re-running the fixed layout: the web front-end
serves 200 on `/` (with `<title>FishE</title>`) and on `/state`, and
`validate_against_schema` resolves schemas/player.json.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dmccoystephenson
dmccoystephenson merged commit 3922dcd into main Aug 1, 2026
1 check passed
@dmccoystephenson
dmccoystephenson deleted the fix/dockerfile-missing-runtime-deps branch August 1, 2026 02:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant