fix(docker): complete the Node and Python image builds - #25
Merged
Conversation
Both images copied only their entrypoint — server.js / server.py — without the modules those files import, so neither could start. Nothing in the repository references them, so the published Go image is unaffected. Each image now copies every module its server imports, and the layout inside the image mirrors the repository, keeping server-node/ and client/ as siblings so the widget resolves at ../client/fcaptcha.js with no configuration. Both are therefore built from the repository root: docker build -f server-node/Dockerfile -t fcaptcha-node . Python keeps `python server.py` rather than a bare uvicorn invocation, because the __main__ block sets proxy_headers=False, which FCaptcha requires so that TRUSTED_PROXIES is the only thing resolving a client address. Verified by running each container: both serve /health, /fcaptcha.js and /api/pow/challenge, and the end-to-end suite against each matches what that server scores natively (Node 93/93, Python 80/93, the latter being the implementation's documented divergences rather than anything the image adds). docker-smoke now covers all three images. Startup, the widget endpoint, the challenge endpoint and the startup log are checked for each; the demo-page assertion stays specific to the published image. These are packaging checks and they cover a gap unit tests cannot: a Dockerfile that copies a file to one path while the server looks in another is valid in isolation and broken in combination, and only running the container reveals it. Also simplifies a comment in resolveClientPath to state the coupling between the candidate list and the Dockerfiles rather than recount how it was found.
cport1
force-pushed
the
fix/node-python-dockerfiles
branch
from
July 28, 2026 14:23
edbfab6 to
3d22a42
Compare
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.
Both images copied only their entrypoint —
server.js/server.py— without the modules those files import, so neither could start. Nothing in the repository references them, and the published Go image is unaffected.Fix
Each image now copies every module its server imports. The layout inside the image mirrors the repository —
server-node/andclient/as siblings — so the widget resolves at../client/fcaptcha.jswith no configuration.Both are therefore built from the repository root:
docker build -f server-node/Dockerfile -t fcaptcha-node .Python keeps
python server.pyrather than a bare uvicorn invocation, because the__main__block setsproxy_headers=False— which FCaptcha requires soTRUSTED_PROXIESis the only thing resolving a client address.Verified by running each container
/fcaptcha.js/api/pow/challengeEach scores exactly what that server scores natively — Python's 13 are the implementation's documented divergences, not something the image introduces.
Coverage
docker-smokenow runs over all three images, checking startup, the widget endpoint, the challenge endpoint and the startup log. The demo-page assertion stays specific to the published image.These are packaging checks, covering a gap unit tests cannot: a Dockerfile that copies a file to one path while the server looks in another is valid in isolation and broken in combination. Only running the container reveals it.