Skip to content

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

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

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

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, hot-reloading preview of this repo's React app. Previously the preview would have been assembled by guesswork at runtime; now the repo itself declares how its frontend is built and started, so previews are predictable and reviewable.

Only one runnable frontend exists here — the create-react-app in web/ — so there is one recipe entry and one dev-mode Dockerfile. Nothing else in the repo is changed. The samples/auth-web/ directory was examined and deliberately left alone: it is loose reference code with no package manifest and nothing imports it, so it is not a runnable app.

Two things were intentionally not done, and both are worth a reviewer's attention. No staging backend URL was recorded, because the repo declares none anywhere (no env files, deploy workflows, or proxy config) and guessing one risks pointing live previews at the wrong data. And no preview CORS change was made to the Django backend in server/, because that backend is same-origin by design and has no CORS surface to extend — details below.

Technical details

Recipe.codepress/dev-server/recipe.json, schema_version: 1, one frontend: working_dir: "web", framework: "cra", package_manager: "yarn", dev_command: "yarn start", install_command: "yarn install --frozen-lockfile", dependency_manifests: ["web/yarn.lock"] (the lockfile is per-app, not at the repo root — there is no workspace), dev_port: 3000, system_packages: ["procps"]. No prebuild_command: start is standalone, and the postbuild script is a production-build hook, not a dev-path dependency.

Base image is the main judgement call. web/ is create-react-app 1.0.10 (webpack 2.6.1, react 15, react-dev-utils 3.0.2) from 2017. The Dockerfile pins public.ecr.aws/docker/library/node:16-bookworm rather than the current LTS, because Node 16 is the newest LTS that predates OpenSSL 3 — that removes the entire ERR_OSSL_EVP_UNSUPPORTED: digital envelope routines::unsupported failure class that sinks 2017-era webpack toolchains on Node 17+, without resorting to --openssl-legacy-provider. I verified the 16-bookworm tag resolves on the ECR public mirror (HTTP 200) so the contract's full-bookworm-not-slim rule still holds, which also matters because the node-gyp toolchain is needed for the runtime dependency install.

No corepack, deliberately. The base image already ships yarn 1.22 on PATH, which is what this repo's yarn lockfile v1 expects. Enabling corepack would shadow that working binary with a shim that fetches yarn from the registry on first use, adding a network dependency to every cold start.

HMR. CRA 1.x has no WDS_SOCKET_PORT support (that landed in CRA 3.4), so there is no client-port knob to wire. Instead react-dev-utils 3.0.2's webpackHotDevClient builds its sockjs URL from window.location, so the HMR websocket rides the page origin and works behind the preview proxy — the same origin-based behaviour as Next.js. The CODEPRESS_HMR_* vars are still declared to keep the runtime contract uniform across frontends. DANGEROUSLY_DISABLE_HOST_CHECK=true is the CRA analogue of Vite's server.allowedHosts: previews are served from an arbitrary *.preview.codepress.dev host, and webpack-dev-server 2.x would otherwise return "Invalid Host header" instead of the app. BROWSER=none stops CRA trying to launch a browser inside the container. All three are scoped to this dev image only.

Image stays thin — no baked node_modules, no source COPY, no CodePress binary. Dependencies arrive at runtime on the bind-mounted checkout. procps is the only system package: the sole native dependency in the lockfile is fsevents (macOS-only and optional, skipped on Linux).

Why no preview CORS edit on server/. The Django app has zero CORS references anywhere (django-cors-headers is absent from INSTALLED_APPS, MIDDLEWARE, and the Pipfile), and it is same-origin by construction: web/package.json's postbuild copies the CRA build into server/static/build/, TEMPLATES.DIRS points there, and the catch-all url(r'^', index_views.index) renders index.html. Django serves the React app itself. web/src also makes no API calls at all — no fetch/axios, no absolute API base URL, no API env var. So there is no cross-origin browser caller and no allowlist to append to. Independently, server/server/settings.py is a single flat module with DEBUG = True hardcoded and no staging environment, which would make a CORS change report-only regardless of the above.

Why no staging_backend_url. No .codepress/verify-staging/recipe.json, no .env* files, no vercel.json, no next/vite config, no .github/workflows/, and no URL in the README. Nothing was persisted rather than recording a guess.

Social sign-in: not applicable. No runnable frontend has it. samples/auth-web/ contains a GithubButton, but that directory has no package.json, no index.html, imports a ../../../config/settings path that does not exist in this repo, and is imported by nothing in web/src.

Changes

  • Add .codepress/dev-server/recipe.json — schema_version 1, one frontend entry for the web/ create-react-app
  • Add .codepress/dev-server/Dockerfile.web — thin dev-mode image pinned to node:16-bookworm for CRA 1.x / OpenSSL-3 compatibility
  • Wire bind + HMR through PORT, HOST/HOSTNAME, CODEPRESS_BIND_HOST, CODEPRESS_HMR_CLIENT_PORT, CODEPRESS_HMR_PROTOCOL
  • Set DANGEROUSLY_DISABLE_HOST_CHECK and BROWSER=none so webpack-dev-server 2.x serves the preview host headlessly

Test plan

  • Build the dev image from the repo root and confirm it succeeds: docker build -f .codepress/dev-server/Dockerfile.web -t ddri-web .
  • Run it with the checkout mounted and deps installed, then confirm the dev server binds all interfaces rather than loopback: docker run --rm -v "$PWD":/app -p 3000:3000 ddri-web sh -c 'cd /app/web && yarn install --frozen-lockfile && yarn start' — expect Compiled successfully and no ERR_OSSL_EVP_UNSUPPORTED
  • Load http://localhost:3000/ and verify the 'Welcome to React' home page renders (not an 'Invalid Host header' page)
  • Edit the <h2> text in web/src/containers/home/Home.js and save; confirm the browser hot-reloads without a manual refresh, and that the console shows the sockjs connection succeeding against the page origin
  • Confirm python3 -c "import json;json.load(open('.codepress/dev-server/recipe.json'))" parses and that dockerfile_path resolves to a file on disk
  • Confirm the diff touches only .codepress/dev-server/ — no backend, frontend, or dependency files were modified

Open items

  • No staging_backend_url was recorded — the repo declares one nowhere, so previews will not pre-fill a backend. If you have a staging API, add it and re-run bootstrap.
  • No preview CORS allowance was added to the Django backend, because it is same-origin (Django serves the CRA build) and has no CORS surface. If you later split the frontend onto its own origin and call server/ cross-origin, that backend will need an anchored preview-origin allowance in a staging-only settings path — which does not exist yet, since settings.py is a single flat module with no staging environment.
  • The node:16-bookworm pin is intentional for CRA 1.0.10 / webpack 2.6.1 and is EOL upstream. It is the pragmatic choice for the app as it stands today; upgrading react-scripts would be the prerequisite for moving the dev image to a current LTS.
  • yarn install --frozen-lockfile resolves a 2017-era yarn lockfile v1. It is the correct reproducible form, but be aware that any package unpublished from the registry since then would surface as an install failure — worth watching on the first build.

Generated with CodePress

Adds .codepress/dev-server/recipe.json (schema_version 1) and one dev-mode
Dockerfile for the single runnable frontend, the create-react-app in web/.

The Dockerfile pins node:16-bookworm: this app is react-scripts 1.0.10 /
webpack 2.6.1 from 2017, and Node 16 is the newest LTS predating OpenSSL 3, so
the old webpack hashing path cannot fail with ERR_OSSL_EVP_UNSUPPORTED. The full
-bookworm variant supplies the node-gyp toolchain for the runtime dependency
install and bundles yarn 1.22, matching the repo's yarn lockfile v1, so no
package manager is fetched at cold start.

CRA 1.x has no WDS_SOCKET_PORT support, so HMR relies on its react-dev-utils
3.0.2 client building the sockjs URL from window.location - the websocket rides
the page origin and works behind the preview proxy. DANGEROUSLY_DISABLE_HOST_CHECK
is set so webpack-dev-server 2.x serves the arbitrary *.preview.codepress.dev
host instead of 'Invalid Host header'.

No staging_backend_url: the repo has no .env files, deploy workflows, or proxy
config declaring one, so nothing was persisted rather than guessing.

No preview CORS edit: the Django backend in server/ has no CORS surface at all
and is same-origin by construction - web/'s postbuild copies the CRA build into
server/static/build/ and the catch-all URL renders it - so it serves no
cross-origin browser client. It also has a single settings.py with no staging
environment, which would make a CORS change report-only regardless.

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