Bootstrap CodePress Live Dev Server recipe + dev Dockerfile - #34
Open
codepress-dev[bot] wants to merge 1 commit into
Open
Conversation
Author the committed Live Dev Server artifacts for this repo so previews boot from repo-owned files instead of a runtime heuristic. Discovery found one runnable frontend, `web/` (Create React App via react-scripts 1.0.10, yarn 1 classic lockfile, dev port 3000), and one backend, `server/` (Django 1.11). The Django app has no CORS surface and no cross-origin caller — it serves the React production build itself — so no preview-CORS edit was made. No staging backend URL was detected anywhere in the repo, so `staging_backend_url` is deliberately omitted rather than guessed. Verified on the same Node/yarn versions the base image ships (node 22.x with the bundled yarn 1.22.22): `yarn install --frozen-lockfile` resolves the 2017 lockfile cleanly, the recipe's `dev_command` compiles and serves HTTP 200 on `$PORT`, binds all interfaces, answers a `*.preview.codepress.dev` Host header, serves `/sockjs-node` with a 101 websocket upgrade, and recompiles on file edits. 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 Live Dev Server for this repo, so that opening a live preview boots the React app from files committed here rather than from a guess made at runtime. Two files are added under
.codepress/dev-server/: a recipe that records how the frontend runs (where it lives, how to install it, the command that starts it, and the port it listens on), and a matching dev-mode Docker image definition for it. Nothing about how the app builds or runs for you locally changes — these files are only read by the preview system.Discovery found one runnable frontend (
web/, a Create React App project) and one backend (server/, Django). The Django API was inspected for preview CORS setup and intentionally left untouched: it has no cross-origin API surface (it serves the built React app itself, same-origin, and has no CORS allowlist ordjango-cors-headersdependency), and the repo has a single settings module with no separate staging environment to scope such a change to. No staging backend URL exists anywhere in the repo, so none was recorded — a guessed or production URL would point previews at the wrong API. The frontend has no social sign-in, so no auth work was needed either.Because this frontend is a 2017-era toolchain (react-scripts 1.0.10 / webpack 2 / React 15), the setup was validated by actually installing and booting it rather than assumed — see the test plan.
Technical details
.codepress/dev-server/recipe.json—schema_version: 1with a singlefrontends[]entry:label: web,working_dir: web,framework: cra,package_manager: yarn,dev_port: 3000,install_command: yarn install --frozen-lockfile,dependency_manifests: ["web/yarn.lock"](the per-app lockfile, not a root one — there is no workspace here),system_packages: ["procps"],size: medium.prebuild_commandis empty: thepostbuildscript (cp -r build/ ../server/static/build/) is production-only and never runs in dev.staging_backend_urlis omitted — there is no.env*,vercel.json, CI workflow, or.codepress/verify-staging/recipe.jsonto detect one from, so nothing was persisted and the Live Dev Server env prefill was skipped.dev_commandissh -c 'HOST="${CODEPRESS_BIND_HOST:-0.0.0.0}" WDS_SOCKET_PORT="${CODEPRESS_HMR_CLIENT_PORT:-443}" BROWSER=none yarn start'. react-scripts readsHOST/PORTfrom env (confirmed against the 1.0.10 source), so CRA'sHOSTis mapped from the CodePress bind var rather than hardcoded..codepress/dev-server/Dockerfile.web— thin, toolchain-only image onpublic.ecr.aws/docker/library/node:22-bookworm(full base, not-slim): noCOPY, no bakednode_modules, no install layer; deps arrive at runtime on the bind-mounted checkout.WORKDIR /app→/app/web,procpsvia apt, the four bind/HMR env vars declared with defaults, andnode_modules/.binprepended toPATHas a backstop.Three decisions worth a close look:
Node 22, and no corepack. The repo pins no Node version, so this uses the current LTS — verified to work, not assumed (webpack 2 defaults to an
md5hash function, so it sidesteps the OpenSSL 3md4breakage that kills webpack 4 on modern Node; only deprecation warnings appear). Corepack is deliberately not enabled:node:22-bookwormalready ships yarn 1.22.22 (verified in the official image Dockerfile), which is exactly what this v1yarn.lockneeds, andcorepack enablewould replace that working binary with a shim that resolves a version at first use — a possible network fetch during a cold start. ARUN yarn --versionassertion fails the build loudly if a future base image ever drops the bundled yarn. Node 18 was also verified to work, if the base ever needs to move back.DANGEROUSLY_DISABLE_HOST_CHECK=truein the dev image. react-scripts 1.x only skips webpack-dev-server's DNS-rebinding host check when noproxyis set inpackage.json— which is the case today, so previews work either way. Setting it explicitly keeps the preview's*.preview.codepress.devHost header accepted if aproxykey is ever added. This is the same role Vite'sserver.allowedHostsplays, and it applies only to this dev-preview image, never to a production build.HMR needs no config shim. react-scripts 1.0.10's hot client builds its SockJS URL from
window.location(verified inreact-dev-utils@4.2.1/webpackHotDevClient.js), so the websocket rides the preview origin overwssautomatically, like Next.js.WDS_SOCKET_PORTis carried for the uniform runtime contract but is inert on this CRA version — worth knowing so nobody later "fixes" HMR by editing config that isn't read.No backend CORS change. Documented rather than silently skipped:
server/server/settings.pyhas nocorsheadersapp, no middleware, and noCORS_*settings, and no frontend code performs anyfetch/XHR (web/src/redux/example.jsis a local-only redux stub). Adding a CORS surface would mean introducing a new Python dependency and inventing a cross-origin contract this app doesn't have — and there is no staging-only config path to scope it to, sincesettings.pyis the single settings module. If a preview later needs the frontend to call this Django API cross-origin, that is an explicit follow-up: adddjango-cors-headers, split out a staging settings module, and allow only the anchored preview-origin pattern there.Changes
.codepress/dev-server/recipe.json— onefrontends[]entry for theweb/CRA app (yarn, port 3000,web/yarn.lockas the dependency fingerprint).codepress/dev-server/Dockerfile.web— thin dev-mode image onnode:22-bookwormthat binds0.0.0.0, installsprocps, and runsyarn startwith HMR wired to the runtime env varsstaging_backend_url— no staging URL exists anywhere in the repo, so none was guessedTest plan
python3 -c "import json;print(json.load(open('.codepress/dev-server/recipe.json'))['frontends'][0])"— one entry,working_dir: web,dev_port: 3000.cd web && yarn install --frozen-lockfileunder Node 22 with yarn 1.22.x. It completed in ~10-27s here with no native build failures (the only native package,fsevents, is darwin-only and is skipped on linux).dev_commandverbatim:cd web && env PORT=3200 CODEPRESS_BIND_HOST=0.0.0.0 CODEPRESS_HMR_CLIENT_PORT=443 DANGEROUSLY_DISABLE_HOST_CHECK=true sh -c 'HOST="$CODEPRESS_BIND_HOST" WDS_SOCKET_PORT="$CODEPRESS_HMR_CLIENT_PORT" BROWSER=none yarn start'→ expect "Compiled successfully!" and a bind on all interfaces (it prints an "On Your Network" URL, not just localhost).curl -o /dev/null -w '%{http_code}' http://127.0.0.1:3200/→ 200;/static/js/bundle.js→ 200;/sockjs-node/info→ 200; and with-H 'Host: <32-hex>-f99e6fb9528a8773.preview.codepress.dev'→ 200 (the preview Host header is accepted).curl -i --max-time 5 -H 'Connection: Upgrade' -H 'Upgrade: websocket' -H 'Sec-WebSocket-Version: 13' -H 'Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==' 'http://127.0.0.1:3200/sockjs-node/1/abc/websocket'→HTTP/1.1 101(the client-side URL is derived fromwindow.location, so it targets the preview origin over wss).web/src/index.jswhile the server runs → the log shows "Compiling..." then "Compiled successfully!".web/src/containers/home/Home.jsappears without a manual restart.Open items
django-cors-headers, introduce a staging settings module, and allow only the anchored preview-origin pattern there — never in the shared/production settings.react-scripts1.0.10 (2017) is what this app pins, so the dev image is validated against that, not upgraded. Node 22 runs it with only deprecation warnings; Node 18 was also verified as a fallback if a future toolchain change breaks it.samples/auth-web/contains a GitHub OAuth button sample, but it is not part of the runnable frontend (no package.json, not imported byweb/src), so no preview social-auth work applied.Authors
Generated with CodePress · View the chat session
Co-authored-by: dev@codepress.dev dev@codepress.dev