Bootstrap CodePress Live Dev Server recipe + dev Dockerfile - #41
Open
codepress-dev[bot] wants to merge 1 commit into
Open
Conversation
Adds the repo-owned Live Dev Server artifacts so previews boot from committed files instead of a runtime heuristic. - .codepress/dev-server/recipe.json: one frontend entry for `web/` (CRA, yarn, port 3000, `yarn install --frozen-lockfile`, fingerprinted on web/yarn.lock). - .codepress/dev-server/Dockerfile.web: thin dev-mode image on the full node:18-bookworm base (no baked node_modules, no source COPY, no CodePress binary). Binds 0.0.0.0 via CODEPRESS_BIND_HOST and sets DANGEROUSLY_DISABLE_HOST_CHECK so webpack-dev-server 2.5.0 accepts the preview proxy's per-session hostname instead of returning "Invalid Host header". No staging backend URL was detected, so none is persisted. The Django API in server/ is served same-origin (its catch-all URL renders the React build), has no CORS allowlist and no staging settings module, so no preview-CORS change was needed. The runnable frontend has no social sign-in. 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 live previews for the React app in
web/. Until now, CodePress had to guess how to boot your frontend each time; this PR adds two small committed files that spell it out explicitly, so a preview starts the same way every time and hot reload works in the browser.The repo's React app is a 2017-era create-react-app (react-scripts 1.0.10), which needed a couple of specific accommodations to run behind a hosted preview URL — those are baked into the files here. Nothing about how you run the app locally changes:
yarn startinweb/behaves exactly as before.Two things were checked and deliberately left alone. The Django API in
server/is served on the same origin as the React build (Django's catch-all route renders the builtindex.html), it has no CORS allowlist, and the frontend makes no cross-origin API calls — so there was no CORS change to make. And no staging backend URL exists anywhere in the repo, so none was recorded rather than guessing one.Technical details
Adds
.codepress/dev-server/recipe.json(schema_version 1) and.codepress/dev-server/Dockerfile.web. The recipe is the backend's source of truth for building one content-addressed dev image per frontend.Discovery. One runnable frontend:
web/— CRA,start: react-scripts start, yarn (web/yarn.lock), default port 3000.samples/auth-web/is not a frontend: nopackage.json, and its files import modules (../../redux/auth,../../../config/settings) and npm packages (query-string,react-spinkit,secure-random) that don't exist inweb/— it's unreachable tutorial reference code.server/is a Django backend (detected, not made into a frontend entry).Recipe fields.
working_dir: "web",framework: "cra",package_manager: "yarn",install_command: "yarn install --frozen-lockfile",dependency_manifests: ["web/yarn.lock"](per-app lockfile, not a root one),dev_port: 3000,system_packages: ["procps"],size: "medium". Noprebuild_command— thepostbuildscript only runs after a productionbuild, so nothing needs pre-building for dev.system_packagesis just theprocpsbaseline: I greppedweb/yarn.lockfor source-built native modules (node-sass, node-gyp, bcrypt, canvas, sharp, natives, fibers, sqlite3) and found none.fsevents@1.1.2is present but isos: ["darwin"], so yarn skips it on linux.The non-obvious part — why
DANGEROUSLY_DISABLE_HOST_CHECK=true. I verified against the actual pinned versions rather than react-scripts' declared ranges:web/yarn.lockresolves react-scripts 1.0.10 → webpack 2.6.1, webpack-dev-server 2.5.0, react-dev-utils 3.0.2. webpack-dev-server 2.5.0'sServer.jsrejects any request whoseHostheader it doesn't recognize withres.send("Invalid Host header")(and applies the same check to the sockjs connection), which would break every request through the preview proxy's unique per-session hostname. react-scripts 1.0.10 setsdisableHostCheck: !proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true'— so today it is off only becauseweb/package.jsonhappens to have noproxyfield. Setting the env var explicitly makes previews robust if someone addsproxylater.HMR needs no client-port wiring. react-dev-utils 3.0.2's
webpackHotDevClient.jsbuilds its SockJS URL fromwindow.location(protocol + hostname + port) plus/sockjs-node, so the websocket rides the page origin and works behind the proxy unchanged.WDS_SOCKET_PORTis still mapped fromCODEPRESS_HMR_CLIENT_PORTin the CMD for the uniform runtime contract and for a future react-scripts upgrade that honors it.Base image:
node:18-bookworm(full, from the public-ECR mirror — never-slim, which strips the node-gyp toolchain the runtime install may need). 18 is the oldest bookworm Node tag and the closest fit for this toolchain. Notably no--openssl-legacy-provideris needed: theERR_OSSL_EVP_UNSUPPORTEDmd4 problem starts at webpack 4, and webpack 2 hashes with md5, which OpenSSL 3 still provides. yarn 1.22.22 is pinned viacorepack prepare --activatewith a build-timeyarn --versionassertion, so a cold start never downloads a package manager.The image is thin per contract: no baked
node_modules, no sourceCOPY, no CodePress binary. It binds viaCODEPRESS_BIND_HOST(default0.0.0.0) and declaresPORT/CODEPRESS_HMR_CLIENT_PORT/CODEPRESS_HMR_PROTOCOL; deps arrive at runtime on the checkout bind-mounted at/app.BROWSER=nonestops CRA trying to open a browser in the container;CI=falsekeeps dev warnings from being escalated.Not done, with reasons. No
staging_backend_url: there is no.env*, no.github/workflows, novercel.json, and no.codepress/verify-staging/recipe.json— nothing to detect, and a guess is worse than nothing. No preview-CORS edit: the Django backend has nocorsheaders, no CORS middleware, noCORS_*settings, and no cross-origin caller (zerofetch/axios/absolute API base URL inweb/src) — it is a same-origin architecture, so there is no CORS surface to extend. It also has only a singlesettings.pywith no staging module, so even if a surface existed this would have been report-only rather than an auto-edit. No preview social-auth work: the runnable frontend has no social sign-in, and the backend installsallauth.accountonly (noallauth.socialaccount, no providers).Changes
.codepress/dev-server/recipe.json— schema_version 1 with a singlewebfrontend entry (CRA / yarn / port 3000), fingerprinted onweb/yarn.lock.codepress/dev-server/Dockerfile.web— thin dev-mode image on fullnode:18-bookworm, binds0.0.0.0viaCODEPRESS_BIND_HOST, pins yarn 1.22.22, installsprocpsDANGEROUSLY_DISABLE_HOST_CHECK=truein the dev image so webpack-dev-server 2.5.0 accepts the preview proxy's per-session hostname instead of returningInvalid Host headerBROWSER=noneandCI=falsesoreact-scripts startbehaves correctly headless in a containerweb/package.json, or the Django backendTest plan
cd web && yarn startstill behaves exactly as before.python3 -m json.tool .codepress/dev-server/recipe.json, then check the single frontend'sdockerfile_pathexists,working_dirisweb, anddev_portis3000.-f):docker build -f .codepress/dev-server/Dockerfile.web -t drx-web-dev .— it should finish in well under a minute since no dependencies are baked, and theyarn --versionstep should print1.22.22.cd web && yarn install --frozen-lockfile(the exact command in the recipe). It should not report that the lockfile needs updating.docker run --rm -p 3000:3000 -v "$PWD":/app drx-web-dev. Expectreact-scripts startto compile and print the "Compiled successfully!" banner, binding all interfaces rather than loopback.http://localhost:3000— the React logo page renders.web/src/containers/home/Home.jsand save. The browser should update without a manual refresh, with nosockjs-nodeconnection errors in the browser console.curl -s -H 'Host: abc123.preview.codepress.dev' http://localhost:3000/ | head -5. It should return the app's HTML, NOT the stringInvalid Host header.Open items
checkHost, react-scripts 1.0.10'swebpackDevServer.config.js, react-dev-utils 3.0.2'swebpackHotDevClient.js) rather than by running them. Step 5 of the test plan is the real check.Dockerfile.web./sockjs-node(websocket upgrade and xhr-streaming) for hot reload to connect. Standard for the platform, but worth watching at step 7 of the test plan if HMR is silent.web/srcmakes no API calls and there is noproxyfield inweb/package.json, so a preview serves the React app alone and theserver/API is not reachable from it. That is the repo's current state, not something this PR changed. If cross-origin API calls are added later, preview CORS on the Django side becomes relevant and this bootstrap can be re-run to handle it.Authors
Generated with CodePress · View the chat session
Co-authored-by: dev@codepress.dev dev@codepress.dev