Skip to content

Bootstrap CodePress Live Dev Server recipe + dev Dockerfile - #47

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

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

Conversation

@codepress-dev

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

Copy link
Copy Markdown

Summary

This sets up the files CodePress needs to boot a live preview of this project's React app. Until now the preview would have had to guess how to run the app; now the repo tells it directly — which app to run, how to install it, and which Node version it needs. The only frontend here is web/, so that's the one preview this adds. Nothing about how the app builds or runs for you locally changes: these are new files under .codepress/, and no existing application code was touched. Two things were deliberately left alone rather than guessed at, and both are explained below: no staging backend URL was recorded (there isn't one declared anywhere in the repo), and the Django API in server/ was not modified for preview CORS, because it currently serves the React build from its own origin and has no cross-origin API surface to open up.

Technical details

Discovery. One runnable frontend: web/ — Create React App, react-scripts 1.0.10, yarn.lock (yarn v1 format, no root workspace), startreact-scripts start, default port 3000. samples/auth-web/ is not a frontend: no package.json, no index.html, imports (../../../config/settings, secure-random) that resolve to nothing in the tree, and no reference from web/src. server/ is a Django 1.11 backend (see the CORS note below).

Node 16 is the load-bearing decision. react-scripts 1.0.10 sits on webpack@2.6.1, which hashes modules with md4. Under Node 17+ (OpenSSL 3) that throws error:0308010C:digital envelope routines::unsupported and the dev server never comes up. Pinning node:16-bookworm (OpenSSL 1.1.1) lets the 2017 toolchain in web/yarn.lock run unmodified, and avoids the alternative of papering over it with NODE_OPTIONS=--openssl-legacy-provider on a newer Node, which would leave the rest of the 2017 dependency tree on an untested runtime. The tag was verified to exist and resolve on the public ECR mirror. Full -bookworm, never -slim, because deps install at runtime and node-gyp needs the toolchain.

No corepack. The repo declares no packageManager, and the Node base image already bundles yarn 1 classic — exactly what this lockfile format needs. Activating an unpinned corepack shim would only add a registry fetch on every cold start.

CRA specifics, verified against the published react-scripts@1.0.10 / react-dev-utils@4.2.3 sources rather than assumed:

  • start.js reads HOST (defaulting to 0.0.0.0) and PORT, so bind is env-driven; the CMD derives HOST from CODEPRESS_BIND_HOST.
  • webpackHotDevClient.js builds its SockJS URL from window.location (protocol/hostname/port), so HMR follows the public preview origin automatically behind the TLS proxy. WDS_SOCKET_PORT is a no-op in CRA 1.x but is mapped from CODEPRESS_HMR_CLIENT_PORT anyway so the wiring stays correct if react-scripts is upgraded.
  • webpackDevServer.config.js computes disableHostCheck: !proxy || DANGEROUSLY_DISABLE_HOST_CHECK === 'true'. web/package.json declares no proxy, so the host check is already off today; the Dockerfile sets the env var explicitly so adding a proxy field later doesn't silently break previews with Invalid Host header. The dev server is only reachable through the CodePress preview proxy.
  • BROWSER=none stops react-scripts from trying to launch a browser inside the container.

Image shape. Thin and toolchain-only: no COPY of source, no baked node_modules, no install layer — the runtime bind-mounts the checkout at /app and provides deps. WORKDIR /app/web, EXPOSE 3000, procps installed for supervisor shutdown, workspace bins prepended to PATH. The Dockerfile CMD and the recipe's dev_command are byte-identical argv (asserted in validation).

Staging backend URL: omitted, not guessed. There is no .codepress/verify-staging/recipe.json, no .env* of any kind, no vercel.json, no next.config/vite.config, and no .github/workflows. Zero candidates, so staging_backend_url is left out entirely rather than written as a placeholder. No Live Dev Server env prefill was done for the same reason — and web/src makes no API calls at all, so there is no framework-public API-base var to prefill even if a URL existed.

Preview CORS: no edit, by design. server/ is a Django backend, but it fails the gate for a preview-CORS change on three independent counts, each verified: (1) it has no CORS surface — django-cors-headers is not in INSTALLED_APPS, not in MIDDLEWARE, not in Pipfile, and not present anywhere in Pipfile.lock; a repo-wide grep for cors / allow_origin / Access-Control returns nothing. (2) It is same-origin by construction — server/server/urls.py routes ^ to a view that renders the React build's index.html, and web/package.json's postbuild copies build/ into server/static/build/. (3) There is no cross-origin caller — web/src contains no fetch/axios/absolute API URL at all. Adding CORS here would mean introducing a new dependency and inventing a surface the app doesn't have. Separately, the repo has a single server/server/settings.py with DEBUG = True and no staging settings module or .env.staging, so there is no staging-only config path to scope an allowance to — which is a report case regardless. If a browser client on another origin is added later, run this bootstrap again and it will detect the CORS surface and wire it.

Preview social auth: not applicable. No social or enterprise sign-in exists in the runnable frontend. The GitHub OAuth button under samples/auth-web/components/ is unreferenced sample code outside any buildable app, so there was nothing to make preview-compatible.

Changes

  • Add .codepress/dev-server/recipe.json — schema_version 1, one frontend entry for web/ (framework cra, package manager yarn, yarn install --frozen-lockfile, dependency manifest web/yarn.lock, dev port 3000, procps, size medium)
  • Add .codepress/dev-server/Dockerfile.web — thin dev-mode image on node:16-bookworm pinned for the webpack 2 / OpenSSL 1.1.1 requirement, binding via CODEPRESS_BIND_HOST and wiring HMR from CODEPRESS_HMR_CLIENT_PORT / CODEPRESS_HMR_PROTOCOL
  • Omit staging_backend_url — no staging URL is declared anywhere in the repo
  • Leave server/ (Django) unmodified — no CORS surface, same-origin architecture, and no staging config path to scope an allowance to

Test plan

  • Confirm the two new files are the entire diff: git diff --stat master...HEAD should show only .codepress/dev-server/recipe.json and .codepress/dev-server/Dockerfile.web, and no application code.
  • Check the recipe parses and matches the app: python3 -c "import json;print(json.load(open('.codepress/dev-server/recipe.json'))['frontends'][0])" — expect working_dir: web, framework: cra, package_manager: yarn, dev_port: 3000.
  • Build the dev image from the repo root: docker build -f .codepress/dev-server/Dockerfile.web -t drx-web-dev . — it should complete in seconds, since it installs only procps and copies no source.
  • Run it against the checkout and confirm the dev server binds all interfaces on 3000: docker run --rm -p 3000:3000 -v "$PWD:/app" drx-web-dev sh -c 'yarn install --frozen-lockfile && BROWSER=none HOST=0.0.0.0 yarn start', then curl -I http://localhost:3000 and expect HTTP 200. (The install runs here only because you are starting the container by hand; in a real preview the platform hydrates node_modules before start.)
  • Confirm the Node pin is doing its job: rerun the same container with node:22-bookworm substituted in the FROM line and verify yarn start fails with error:0308010C:digital envelope routines::unsupported — that failure is the reason the Dockerfile pins Node 16.
  • Verify hot reload end-to-end: with the container running, edit the heading text in web/src/containers/home/Home.js and confirm the browser at http://localhost:3000 updates without a manual refresh.
  • Spot-check the CORS claim rather than taking it on trust: grep -rniE 'cors|allow_origin|Access-Control' server/ should return nothing, and server/server/urls.py should still route ^ to index_views.index.

Open items

  • The dev image was not built or booted in this session — no Docker daemon was available. What was verified: the node:16-bookworm manifest resolves on the public ECR mirror, the recipe/Dockerfile pass the contract checks, CMD and dev_command are identical argv, and CRA 1.0.10's HOST/PORT/host-check/HMR-socket behavior was read from the published package sources rather than assumed. The first real build happens on the platform side; the test plan above reproduces it locally.
  • yarn install --frozen-lockfile resolves a 2017 dependency tree from the public npm registry. It should be fine (all tarballs are still published, and fsevents is darwin-gated so it is skipped on Linux), but it was not executed here and is the most likely source of a first-build surprise.
  • DANGEROUSLY_DISABLE_HOST_CHECK=true is set in the dev image. It changes nothing today — CRA already computes disableHostCheck: true because web/package.json has no proxy field — and it only guards against a future proxy addition silently breaking previews. Say the word if you would rather it were dropped and the breakage surfaced instead.
  • Previews will not reach the Django API in server/. That is correct for the repo as it stands (the React app makes no API calls), but if you wire the frontend to /api/auth/... against a separately hosted backend later, that backend will need a preview-origin CORS allowance — rerun this bootstrap in whichever repo the backend lives in.

Authors

Generated with CodePress · View the chat session

Co-authored-by: dev@codepress.dev dev@codepress.dev

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

- .codepress/dev-server/recipe.json: one frontend entry for web/ (Create React
  App, yarn, port 3000).
- .codepress/dev-server/Dockerfile.web: thin dev-mode image on
  node:16-bookworm. Node 16 is deliberate — react-scripts 1.0.10 runs webpack
  2.6.1, whose md4 module hashing fails on Node 17+/OpenSSL 3. Binds via
  CODEPRESS_BIND_HOST, bakes no node_modules or source, and maps the runtime's
  public HMR port into the dev command.

No staging backend URL was found anywhere in the repo, so staging_backend_url is
omitted rather than guessed. The Django API in server/ is left untouched: it
renders the React build same-origin, ships no CORS surface, and has no staging
settings path, so there is no preview-CORS change to make safely.

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 27, 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