Skip to content

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

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

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

Conversation

@codepress-dev

@codepress-dev codepress-dev Bot commented Jul 27, 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 rather than guessing how to run it. Exploring the repo turned up one runnable frontend — web/, a Create React App app — and one Django backend in server/. This PR adds two files under .codepress/dev-server/ describing how to build and start the frontend. Nothing about how the app currently builds, runs, or deploys changes: no existing file is touched, and the new files are inert unless CodePress is starting a preview.

Two things were deliberately not done, both because doing them would have meant guessing. No staging backend URL was recorded — the repo has nothing to detect one from — so the preview UI just won't pre-fill a backend. And no CORS change was made to the Django backend: this app is same-origin by design (Django serves the built React app itself), so there is no cross-origin API call for a preview to be blocked on. Details for both are in the technical notes below.

Technical details

recipe.jsonschema_version: 1 with a single web frontend entry: working_dir: "web", framework: "cra", package_manager: "yarn" (from web/yarn.lock; no packageManager field), install_command: "yarn install --frozen-lockfile", dependency_manifests: ["web/yarn.lock"], dev_port: 3000, system_packages: ["procps"], size: "medium". No prebuild_commandweb/package.json's start script is a plain react-scripts start with no build prefix or predev hook.

Dockerfile.web — thin, dev-mode, toolchain-only: no node_modules baked, no source COPY, no CodePress binary. Deps are provided at runtime against the bind-mounted checkout.

The one judgement call worth reviewing is the node:16-bookworm base. web/yarn.lock resolves react-scripts@1.0.10webpack@2.6.1 / webpack-dev-server@2.5.0, against React 15 — a 2017-era toolchain. The repo pins no Node version (no .nvmrc, no engines.node), so defaulting to current LTS risked an image whose dev server never boots. react-scripts@1.0.10 declares engines: {node: ">=6"}, and Node 16 is the newest major that comfortably runs this chain. It is EOL, which is a real trade-off, but this image only ever runs an ephemeral preview container — it is not a deployment artifact. Upgrading react-scripts would let this move forward, but that is an app change, out of scope here.

Three HMR/bind assumptions in the Dockerfile were verified against the actual pinned package sources rather than assumed:

  • react-scripts@1.0.10/config/webpackDevServer.config.js sets disableHostCheck: !proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true'. web/package.json declares no proxy, so the host check is already off; the env var in the CMD is a guard for if a proxy field is ever added, which would otherwise start rejecting the preview Host header.
  • scripts/start.js reads process.env.HOST and process.env.PORT, so the bind address stays runtime-driven via CODEPRESS_BIND_HOST — no localhost/127.0.0.1 literal anywhere in the image.
  • react-dev-utils@3.0.2/webpackHotDevClient.js builds its SockJS URL from window.location (protocol/hostname/port), so HMR rides the preview origin and works behind the proxy given websocket upgrades. WDS_SOCKET_PORT does not exist in this version — it is set as a harmless no-op that becomes correct if react-scripts is upgraded, and the comment says so.

Why no staging_backend_url: there is no .env.staging, .env.example, vercel.json, next/vite config, .github/workflows/, or .codepress/verify-staging/recipe.json in the repo — no candidate source at all. The field is omitted rather than guessed, per the rule that it must never carry a production URL or a guess. Consequently the frontend backend-URL env prefill was also skipped (it is gated on a confident staging URL), and web/src reads no API-base env var to prefill anyway.

Why no preview-CORS edit on server/: the Django backend does have API routes (/api/auth/ via rest_auth), but it fails the cross-origin gate on both signals. It configures no CORS whatsoever — django-cors-headers is not in INSTALLED_APPS, MIDDLEWARE, or Pipfile — and web/src makes zero HTTP calls (no fetch, no axios, no absolute API base URL). The architecture is explicitly same-origin: web/package.json's postbuild copies the CRA build into server/static/build/, TEMPLATES.DIRS points there, and server/urls.py ends with a catch-all url(r'^', index_views.index) serving index.html for pushState. A backend with no CORS surface and no cross-origin caller needs no preview allowance.

Separately, even if a cross-origin call existed, this repo has no staging environment to scope the change to — server/server/settings.py is a single module with DEBUG = True, ALLOWED_HOSTS = [], and SQLite, with no split settings package, no .env.staging, and no env-based settings switch. Preview CORS must never be added to base/shared/production config, so that path would be report-only regardless. See open items.

Changes

  • Add .codepress/dev-server/recipe.json — schema_version 1, one web frontend entry (CRA, yarn, port 3000)
  • Add .codepress/dev-server/Dockerfile.web — thin dev-mode image on node:16-bookworm, binds via CODEPRESS_BIND_HOST, wires HMR to the CODEPRESS_HMR_* env vars, installs procps, bakes no deps or source
  • No existing repo file is modified — no backend CORS edit, no staging URL, no auth changes

Test plan

  • Confirm the diff touches only the two new files under .codepress/dev-server/ and modifies nothing else: git diff --stat origin/master...HEAD
  • Validate the recipe parses and matches the app: python3 -c "import json; r=json.load(open('.codepress/dev-server/recipe.json')); print(r['schema_version'], r['frontends'][0]['working_dir'], r['frontends'][0]['dev_port'])" → expect 1 web 3000, and confirm dev_port 3000 matches CRA's default for web/package.json's start script
  • Build the dev image from the repo root (this was NOT run — no container runtime was available in the bootstrap environment): docker build -f .codepress/dev-server/Dockerfile.web -t drx-web-dev . — expect a successful build and yarn --version to resolve during it
  • Boot a preview and verify the app renders with hot reload: start the Live Dev Server for this repo, open the preview URL, confirm the React page loads, then edit web/src/containers/home/Home.js and confirm the browser updates without a manual refresh (HMR rides the preview origin via SockJS)
  • Sanity-check the container binds correctly: docker run --rm -p 3000:3000 -v "$PWD:/app" drx-web-dev after a yarn install in web/, then curl -I http://localhost:3000 → expect HTTP 200 and no 'Invalid Host header' in the logs

Open items

  • The image was NOT built and the dev server was NOT booted — the bootstrap environment had no container runtime. The node:16-bookworm base tag was confirmed to exist on the public.ecr.aws/docker/library mirror, and the HMR/bind/host-check behavior was verified by reading the pinned react-scripts@1.0.10 and react-dev-utils@3.0.2 sources, but the first real build/boot is unverified. The first preview claim is the actual test.
  • node:16-bookworm is EOL and pinned deliberately (see technical details). If web/'s react-scripts is ever upgraded, bump this base to current LTS and drop the DANGEROUSLY_DISABLE_HOST_CHECK guard — WDS_SOCKET_PORT in the CMD then starts doing real work.
  • yarn install --frozen-lockfile against a 2017 lockfile is assumed to still resolve from the registry; not exercised here. If a package has since been unpublished, the runtime install is where that surfaces.
  • No preview CORS was configured on server/, because the app is same-origin today and has no staging environment to scope such a change to. If you later add a cross-origin frontend that calls this Django API from a preview, you will need: django-cors-headers as a dependency, corsheaders.middleware.CorsMiddleware above CommonMiddleware, and CORS_ALLOWED_ORIGIN_REGEXES = [r"^https://[0-9a-f]{32}-77870fcbd301c2a8\.preview\.codepress\.dev$"] — added to a staging-only settings module, never to base or production config.
  • samples/auth-web/ contains sample login/signup components including a GitHub OAuth button, but they are loose files with no package.json and are not imported by web/src, so they are not a runnable frontend and no social-auth preview wiring was applied. If that flow is ever wired into web/, preview sign-in will need the relay callback registered with the provider.

Authors

Generated with CodePress

Author the committed Live Dev Server artifacts so previews boot from
repo-owned files instead of a runtime heuristic.

Discovery found one runnable frontend, web/ (Create React App 1.0.10,
yarn, dev port 3000), and one Django backend, server/.

- .codepress/dev-server/recipe.json: schema_version 1 with a single
  "web" frontend entry.
- .codepress/dev-server/Dockerfile.web: thin, dev-mode, toolchain-only
  image. Pins node:16-bookworm because this app is webpack 2.6.1 /
  webpack-dev-server 2.5.0 / React 15 and the repo pins no Node version
  of its own. Binds via CODEPRESS_BIND_HOST, wires HMR to the
  CODEPRESS_HMR_* env vars, bakes no node_modules and no source.

No staging backend URL was persisted: the repo has no .env.staging,
.env.example, CI workflow, or verify-staging recipe to detect one from,
and the recipe must never carry a guess or a production URL.

No preview-CORS edit was made. server/ configures no CORS at all and
web/ makes no cross-origin API calls -- the app is same-origin by
design (web/ postbuild copies the CRA build into server/static/build/
and Django serves it from a catch-all route), so there is no
cross-origin surface to allow the preview origin on.

Co-authored-by: dev@codepress.dev <dev@codepress.dev>
@codepress-dev codepress-dev Bot added the cp:in-progress CodePress: still being worked on label Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cp:in-progress CodePress: still being worked on

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants