Bootstrap CodePress Live Dev Server recipe + dev Dockerfile - #52
Open
codepress-dev[bot] wants to merge 1 commit into
Open
Conversation
Adds .codepress/dev-server/recipe.json (schema_version 1) and one dev-mode Dockerfile for the single runnable frontend, the create-react-app in web/. The Dockerfile pins node:16-bookworm: this app is react-scripts 1.0.10 / webpack 2.6.1 from 2017, and Node 16 is the newest LTS predating OpenSSL 3, so the old webpack hashing path cannot fail with ERR_OSSL_EVP_UNSUPPORTED. The full -bookworm variant supplies the node-gyp toolchain for the runtime dependency install and bundles yarn 1.22, matching the repo's yarn lockfile v1, so no package manager is fetched at cold start. CRA 1.x has no WDS_SOCKET_PORT support, so HMR relies on its react-dev-utils 3.0.2 client building the sockjs URL from window.location - the websocket rides the page origin and works behind the preview proxy. DANGEROUSLY_DISABLE_HOST_CHECK is set so webpack-dev-server 2.x serves the arbitrary *.preview.codepress.dev host instead of 'Invalid Host header'. No staging_backend_url: the repo has no .env files, deploy workflows, or proxy config declaring one, so nothing was persisted rather than guessing. No preview CORS edit: the Django backend in server/ has no CORS surface at all and is same-origin by construction - web/'s postbuild copies the CRA build into server/static/build/ and the catch-all URL renders it - so it serves no cross-origin browser client. It also has a single settings.py with no staging environment, which would make a CORS change report-only regardless. Co-authored-by: dev@codepress.dev <dev@codepress.dev>
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.
Summary
This sets up the files CodePress needs to boot a live, hot-reloading preview of this repo's React app. Previously the preview would have been assembled by guesswork at runtime; now the repo itself declares how its frontend is built and started, so previews are predictable and reviewable.
Only one runnable frontend exists here — the create-react-app in
web/— so there is one recipe entry and one dev-mode Dockerfile. Nothing else in the repo is changed. Thesamples/auth-web/directory was examined and deliberately left alone: it is loose reference code with no package manifest and nothing imports it, so it is not a runnable app.Two things were intentionally not done, and both are worth a reviewer's attention. No staging backend URL was recorded, because the repo declares none anywhere (no env files, deploy workflows, or proxy config) and guessing one risks pointing live previews at the wrong data. And no preview CORS change was made to the Django backend in
server/, because that backend is same-origin by design and has no CORS surface to extend — details below.Technical details
Recipe —
.codepress/dev-server/recipe.json,schema_version: 1, one frontend:working_dir: "web",framework: "cra",package_manager: "yarn",dev_command: "yarn start",install_command: "yarn install --frozen-lockfile",dependency_manifests: ["web/yarn.lock"](the lockfile is per-app, not at the repo root — there is no workspace),dev_port: 3000,system_packages: ["procps"]. Noprebuild_command:startis standalone, and thepostbuildscript is a production-build hook, not a dev-path dependency.Base image is the main judgement call.
web/is create-react-app1.0.10(webpack2.6.1, react15, react-dev-utils3.0.2) from 2017. The Dockerfile pinspublic.ecr.aws/docker/library/node:16-bookwormrather than the current LTS, because Node 16 is the newest LTS that predates OpenSSL 3 — that removes the entireERR_OSSL_EVP_UNSUPPORTED: digital envelope routines::unsupportedfailure class that sinks 2017-era webpack toolchains on Node 17+, without resorting to--openssl-legacy-provider. I verified the16-bookwormtag resolves on the ECR public mirror (HTTP 200) so the contract's full-bookworm-not-slimrule still holds, which also matters because the node-gyp toolchain is needed for the runtime dependency install.No corepack, deliberately. The base image already ships yarn 1.22 on PATH, which is what this repo's
yarn lockfile v1expects. Enabling corepack would shadow that working binary with a shim that fetches yarn from the registry on first use, adding a network dependency to every cold start.HMR. CRA 1.x has no
WDS_SOCKET_PORTsupport (that landed in CRA 3.4), so there is no client-port knob to wire. Instead react-dev-utils 3.0.2'swebpackHotDevClientbuilds its sockjs URL fromwindow.location, so the HMR websocket rides the page origin and works behind the preview proxy — the same origin-based behaviour as Next.js. TheCODEPRESS_HMR_*vars are still declared to keep the runtime contract uniform across frontends.DANGEROUSLY_DISABLE_HOST_CHECK=trueis the CRA analogue of Vite'sserver.allowedHosts: previews are served from an arbitrary*.preview.codepress.devhost, and webpack-dev-server 2.x would otherwise return "Invalid Host header" instead of the app.BROWSER=nonestops CRA trying to launch a browser inside the container. All three are scoped to this dev image only.Image stays thin — no baked
node_modules, no sourceCOPY, no CodePress binary. Dependencies arrive at runtime on the bind-mounted checkout.procpsis the only system package: the sole native dependency in the lockfile isfsevents(macOS-only and optional, skipped on Linux).Why no preview CORS edit on
server/. The Django app has zero CORS references anywhere (django-cors-headersis absent fromINSTALLED_APPS,MIDDLEWARE, and thePipfile), and it is same-origin by construction:web/package.json'spostbuildcopies the CRA build intoserver/static/build/,TEMPLATES.DIRSpoints there, and the catch-allurl(r'^', index_views.index)rendersindex.html. Django serves the React app itself.web/srcalso makes no API calls at all — nofetch/axios, no absolute API base URL, no API env var. So there is no cross-origin browser caller and no allowlist to append to. Independently,server/server/settings.pyis a single flat module withDEBUG = Truehardcoded and no staging environment, which would make a CORS change report-only regardless of the above.Why no
staging_backend_url. No.codepress/verify-staging/recipe.json, no.env*files, novercel.json, no next/vite config, no.github/workflows/, and no URL in the README. Nothing was persisted rather than recording a guess.Social sign-in: not applicable. No runnable frontend has it.
samples/auth-web/contains aGithubButton, but that directory has nopackage.json, noindex.html, imports a../../../config/settingspath that does not exist in this repo, and is imported by nothing inweb/src.Changes
.codepress/dev-server/recipe.json— schema_version 1, one frontend entry for theweb/create-react-app.codepress/dev-server/Dockerfile.web— thin dev-mode image pinned tonode:16-bookwormfor CRA 1.x / OpenSSL-3 compatibilityPORT,HOST/HOSTNAME,CODEPRESS_BIND_HOST,CODEPRESS_HMR_CLIENT_PORT,CODEPRESS_HMR_PROTOCOLDANGEROUSLY_DISABLE_HOST_CHECKandBROWSER=noneso webpack-dev-server 2.x serves the preview host headlesslyTest plan
docker build -f .codepress/dev-server/Dockerfile.web -t ddri-web .docker run --rm -v "$PWD":/app -p 3000:3000 ddri-web sh -c 'cd /app/web && yarn install --frozen-lockfile && yarn start'— expectCompiled successfullyand noERR_OSSL_EVP_UNSUPPORTEDhttp://localhost:3000/and verify the 'Welcome to React' home page renders (not an 'Invalid Host header' page)<h2>text inweb/src/containers/home/Home.jsand save; confirm the browser hot-reloads without a manual refresh, and that the console shows the sockjs connection succeeding against the page originpython3 -c "import json;json.load(open('.codepress/dev-server/recipe.json'))"parses and thatdockerfile_pathresolves to a file on disk.codepress/dev-server/— no backend, frontend, or dependency files were modifiedOpen items
staging_backend_urlwas recorded — the repo declares one nowhere, so previews will not pre-fill a backend. If you have a staging API, add it and re-run bootstrap.server/cross-origin, that backend will need an anchored preview-origin allowance in a staging-only settings path — which does not exist yet, sincesettings.pyis a single flat module with no staging environment.node:16-bookwormpin is intentional for CRA 1.0.10 / webpack 2.6.1 and is EOL upstream. It is the pragmatic choice for the app as it stands today; upgrading react-scripts would be the prerequisite for moving the dev image to a current LTS.yarn install --frozen-lockfileresolves a 2017-erayarn lockfile v1. It is the correct reproducible form, but be aware that any package unpublished from the registry since then would surface as an install failure — worth watching on the first build.Generated with CodePress