Skip to content

Bootstrap CodePress Live Dev Server recipe + dev Dockerfiles - #46

Open
codepress-dev[bot] wants to merge 1 commit into
masterfrom
codepress/dev@codepress.dev/bootstrap-live-dev-server-artifacts-bfa6fe76
Open

Bootstrap CodePress Live Dev Server recipe + dev Dockerfiles#46
codepress-dev[bot] wants to merge 1 commit into
masterfrom
codepress/dev@codepress.dev/bootstrap-live-dev-server-artifacts-bfa6fe76

Conversation

@codepress-dev

@codepress-dev codepress-dev Bot commented Jul 26, 2026

Copy link
Copy Markdown

Summary

This sets up the Live Dev Server for this repo, so CodePress can spin up a live, hot-reloading preview of the React app straight from files committed here instead of guessing how to run it at boot time.

Exploring the repo turned up one runnable frontend — the Create React App in web/ — plus the Django API in server/. This PR adds two files under .codepress/dev-server/ describing how to build and start that frontend. Nothing about how the app currently runs for you locally changes; these files are only read by CodePress previews.

Worth flagging: web/ pins react-scripts 1.0.10 (from 2017), which is old enough that "will it even start on a modern Node?" was a real risk. Rather than assume, I installed the dependencies and actually booted the dev server against the exact settings in this Dockerfile — it compiles and serves cleanly. Details in the test plan below.

No CORS changes were needed. Your React app and Django API are served from the same origin (web's postbuild copies the build into server/static/build/, and Django's catch-all route renders it), so a preview has no cross-origin call to fail. Nothing was changed in server/.

Technical details

.codepress/dev-server/recipe.jsonschema_version: 1 with a single frontend entry: label: web, working_dir: web, dev_command: yarn start, framework: cra, package_manager: yarn, install_command: yarn install --frozen-lockfile, dependency_manifests: ["web/yarn.lock"] (a per-app lockfile — there is no root one), dev_port: 3000, system_packages: ["procps"], size: small.

.codepress/dev-server/Dockerfile.web — thin, toolchain-only image on the full node:22-bookworm base (pulled from the public-ECR mirror). No baked node_modules, no source COPY; deps arrive at runtime on the bind-mounted checkout.

Decisions worth a look:

  • Node 22, not an era-appropriate old Node. react-scripts 1.0.10 is webpack 3, so I checked rather than guessed. A clean yarn install --frozen-lockfile plus a dev-server boot both succeed on Node 22 (also verified on Node 18). I initially expected to need NODE_OPTIONS=--openssl-legacy-provider for the classic OpenSSL 3 hash failure, tested without it, and confirmed it is not required — webpack 3 hashes with md5, not the md4 that OpenSSL 3 moved to the legacy provider. So the flag is deliberately absent rather than cargo-culted in.

  • HOST, not HOSTNAME. react-scripts reads its bind address from HOST; the platform contract supplies CODEPRESS_BIND_HOST. The CMD maps one onto the other at run time (HOST="${CODEPRESS_BIND_HOST:-0.0.0.0}" ... yarn start) rather than freezing it into an ENV, so a runtime override is still honored. Verified: overriding PORT=4500 moved the server to 4500.

  • WDS_SOCKET_PORT is mapped but is a documented no-op here. I read the actual react-dev-utils 3.x webpackHotDevClient shipped by this version: it builds its SockJS URL from window.location, so behind the preview proxy HMR already connects to wss://<preview-host>/sockjs-node on 443 with no wiring. WDS_SOCKET_PORT only exists in react-scripts 3.4+. It is mapped for contract uniformity and takes effect as written if react-scripts is ever upgraded; the comment in the Dockerfile says so rather than implying it does something today.

  • DANGEROUSLY_DISABLE_HOST_CHECK=true is defensive, not currently load-bearing. This version computes disableHostCheck: !proxy || DANGEROUSLY_DISABLE_HOST_CHECK === 'true'. web/package.json sets no proxy, so the host check is already off and a request carrying a preview Host header returns 200 today. Setting it keeps previews working if someone later adds a proxy field.

  • system_packages is just procps. The only node-gyp package in web/yarn.lock is fsevents, which is darwin-only and skipped on Linux, so nothing builds from source and no apt library is needed.

  • staging_backend_url is omitted. There is no .env*, no CI workflow, no vercel.json, and no verify-staging recipe in the tree — zero candidates, so nothing was persisted rather than a guess. Consequently the frontend env-var prefill step was skipped too.

  • Preview CORS: correctly a no-op. The gate needs a backend that serves cross-origin browser clients. server/ has no django-cors-headers dependency, no corsheaders in INSTALLED_APPS/MIDDLEWARE, and no CORS setting anywhere; web/src makes no API calls at all and reads no absolute API base URL. Independently, the repo has a single settings.py with no staging module, no settings package, and no .env.staging — no staging-only config path — so even had the gate passed, this would have been report-only rather than an edit to production config.

  • Social auth: not applicable. samples/auth-web/ contains a GitHub OAuth button, but it is detached reference code — it has no package.json, is imported by nothing, and imports modules that do not exist in this repo (../../../config/settings, ../../redux/auth, ../header/Header) plus deps absent from web/package.json. It cannot compile and is not part of a runnable frontend, so the preview social-auth skill was not invoked.

Changes

  • Add .codepress/dev-server/recipe.json declaring the single web CRA frontend (yarn, port 3000, per-app lockfile fingerprint)
  • Add .codepress/dev-server/Dockerfile.web: thin node:22-bookworm dev image binding 0.0.0.0, installing procps, pinning Yarn Classic via corepack
  • Map CODEPRESS_BIND_HOST onto react-scripts' HOST and CODEPRESS_HMR_CLIENT_PORT onto WDS_SOCKET_PORT at run time in the CMD
  • Set BROWSER=none and DANGEROUSLY_DISABLE_HOST_CHECK=true for headless, proxied operation
  • No changes to server/ or web/ — no CORS edit and no HMR config shim were required

Test plan

  • Confirm the recipe is well-formed: python3 -c "import json;print(json.load(open('.codepress/dev-server/recipe.json'))['frontends'][0])" — expect one entry with working_dir web, dev_port 3000, framework cra.
  • Reproduce the dev-server boot the way the image will: cd web && yarn install --frozen-lockfile, then HOST=0.0.0.0 PORT=3000 BROWSER=none yarn start on Node 22. Expect Compiled successfully!.
  • Verify it serves: curl -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3000/ → 200, and that the HTML contains id="root".
  • Verify the preview host is accepted (no webpack 'Invalid Host header'): curl -o /dev/null -w '%{http_code}\n' -H 'Host: 0123456789abcdef0123456789abcdef-8d7329d07b7e6057.preview.codepress.dev' http://127.0.0.1:3000/ → 200.
  • Verify the HMR websocket endpoint is live: curl http://127.0.0.1:3000/sockjs-node/info → JSON with "websocket":true.
  • Verify the runtime PORT override the platform relies on: re-run the CMD with PORT=4500 and confirm the server binds 4500 instead of 3000.
  • After merge, open a CodePress preview and confirm the app renders and an edit to web/src/containers/home/Home.js hot-reloads in the browser.

Open items

  • I could not build or run the actual Docker image — no Docker daemon is available in this bootstrap environment. I validated the layer the Dockerfile controls instead: a clean yarn install --frozen-lockfile and the Dockerfile's literal CMD string, run under its exact ENV block on Node 22. The first real image build will exercise the apt/corepack layers.
  • HMR behind the preview proxy is verified only to the extent that the /sockjs-node endpoint responds and the client derives its URL from window.location (confirmed by reading the shipped react-dev-utils 3.x source). An actual browser hot-reload through the proxy is worth eyeballing on the first preview.
  • react-scripts 1.0.10 is ~8 years old and unmaintained. It works today on Node 22, but this is the pin most likely to break on a future Node. Out of scope here, but worth a planned upgrade.
  • If you later point web/ at the Django API cross-origin (rather than the current same-origin build-copy setup), previews will need django-cors-headers plus a staging-scoped allowance for the preview origin — neither exists today, so nothing was added.

Generated with CodePress

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 Classic, port 3000) and one backend
(server/, Django 1.11 + DRF).

- .codepress/dev-server/recipe.json: single "web" frontend entry.
- .codepress/dev-server/Dockerfile.web: thin, toolchain-only dev image on
  the full node:22-bookworm base. Binds 0.0.0.0, installs procps, pins
  Yarn Classic via corepack, bakes no node_modules and no source.

react-scripts reads the bind address from HOST rather than HOSTNAME, so
the CMD maps CODEPRESS_BIND_HOST onto HOST at run time; that keeps a
runtime override working instead of freezing it in at build time.

No preview-CORS change: the Django app has no CORS surface and no
cross-origin caller. web/'s postbuild copies the React build into
server/static/build/ and Django's catch-all route renders it, so the app
and API share one origin. The repo also has no staging-only config path,
which would make a CORS edit report-only regardless.

No staging backend URL was detected, so staging_backend_url is omitted
rather than guessed.

Co-authored-by: dev@codepress.dev <dev@codepress.dev>
@codepress-dev codepress-dev Bot added the cp:ready-for-review CodePress: finished and ready for review label Jul 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cp:ready-for-review CodePress: finished and ready for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants