From 48c0e6091d350a9a2786d19ea3c80f63f5c62502 Mon Sep 17 00:00:00 2001 From: "codepress-dev[bot]" <202219725+codepress-dev[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2026 06:36:34 +0000 Subject: [PATCH] Bootstrap CodePress Live Dev Server recipe + dev Dockerfile Adds the repo-committed Live Dev Server artifacts so previews boot from this repo instead of a runtime heuristic: - .codepress/dev-server/recipe.json - one frontend entry for web/ (CRA, yarn, port 3000) - .codepress/dev-server/Dockerfile.web - thin dev-mode image (no baked node_modules, no source COPY) that binds 0.0.0.0 and wires HMR to env vars Node 18 is pinned because this app is Create React App 1.0.10 (webpack 2.6.1 / webpack-dev-server 2.5.0). Verified during bootstrap that yarn install --frozen-lockfile + react-scripts start compile and serve on Node 18.20.8, honor PORT, bind all interfaces, answer a preview-style Host header with HTTP 200, and expose a live /sockjs-node HMR endpoint. No staging backend URL was detected (repo has no .env*, CI, or deploy config), so staging_backend_url is intentionally omitted. No preview-CORS change was needed: the Django app in server/ serves the built React bundle same-origin and has no CORS surface or cross-origin caller. Co-authored-by: dev@codepress.dev --- .codepress/dev-server/Dockerfile.web | 71 ++++++++++++++++++++++++++++ .codepress/dev-server/recipe.json | 22 +++++++++ 2 files changed, 93 insertions(+) create mode 100644 .codepress/dev-server/Dockerfile.web create mode 100644 .codepress/dev-server/recipe.json diff --git a/.codepress/dev-server/Dockerfile.web b/.codepress/dev-server/Dockerfile.web new file mode 100644 index 0000000..28c279e --- /dev/null +++ b/.codepress/dev-server/Dockerfile.web @@ -0,0 +1,71 @@ +# Generated by CodePress bootstrap-dev-server. +# Dev-mode image for the "web" frontend (Live Dev Server). +# Edits are preserved, but running /codepress-bootstrap-dev-server again may overwrite them. + +# Node 18 is pinned deliberately. This app is Create React App 1.0.10 +# (webpack 2.6.1 / webpack-dev-server 2.5.0), and 18 is the oldest Node LTS with a +# Debian bookworm image. Verified during bootstrap: `yarn install --frozen-lockfile` +# followed by `react-scripts start` compiles and serves successfully on Node 18.20.8. +# webpack 2.6.1 defaults `output.hashFunction` to md5 (not md4), so no OpenSSL 3 +# legacy-provider workaround is required. +# +# Use the FULL -bookworm image, never -slim: dependencies install at run time +# inside this image, and node-gyp needs the make/gcc/g++/python3 toolchain that +# -slim strips out. +FROM public.ecr.aws/docker/library/node:18-bookworm + +# System packages the dev runtime needs. `procps` only: this frontend's dependency +# tree contains no source-built native module (fsevents is darwin-only and is +# skipped on linux), so no extra apt library is required. +RUN apt-get update \ + && apt-get install -y --no-install-recommends procps \ + && rm -rf /var/lib/apt/lists/* + +# Bake the package-manager binary so a cold MicroVM start does not have to fetch +# it from the public registry before the dev command can run. The repo ships a +# yarn v1 (classic) lockfile and declares no `packageManager` field, so pin yarn +# classic explicitly. This bakes only the yarn shim -- never app dependencies. +RUN corepack enable && corepack prepare yarn@1.22.22 --activate + +WORKDIR /app + +# THIN image: no `node_modules`, no source COPY. The dev-server runtime provides +# dependencies at run time (squashfs hydration, or `yarn install --frozen-lockfile` +# inside this image against the bind-mounted checkout). Only the toolchain lives here. + +# HMR + bind config. Values come from the runtime, never hardcoded -- these are +# only defaults. BROWSER=none stops react-scripts from trying to launch a browser +# inside the container. +ENV HOSTNAME=0.0.0.0 \ + CODEPRESS_BIND_HOST=0.0.0.0 \ + HOST=0.0.0.0 \ + PORT=3000 \ + BROWSER=none \ + CODEPRESS_HMR_CLIENT_PORT=443 \ + CODEPRESS_HMR_PROTOCOL=wss + +WORKDIR /app/web +EXPOSE 3000 + +# Put this frontend's bins on PATH as a backstop so anything that shells out to a +# bare binary still resolves node_modules/.bin. These dirs are populated at run +# time on the bind-mounted checkout. Prepend, never replace, ${PATH} so the +# corepack/yarn shims survive. +ENV PATH="/app/web/node_modules/.bin:/app/node_modules/.bin:${PATH}" + +# Dev command (HMR on), routed through yarn's script indirection rather than a +# bare binary. `react-scripts start` reads HOST and PORT from the environment, so +# the bind address is mapped from CODEPRESS_BIND_HOST at run time instead of baked. +# +# HMR: CRA 1.x's webpackHotDevClient builds its SockJS URL from window.location +# (protocol / hostname / port) plus `/sockjs-node`, so the websocket already +# follows the public preview origin through the proxy and needs no client-port +# flag. WDS_SOCKET_PORT is still mapped from CODEPRESS_HMR_CLIENT_PORT to keep the +# uniform runtime contract -- react-scripts only reads it from 3.4 onward, so it is +# a harmless no-op today and keeps working if CRA is upgraded later. +# +# Host header: CRA 1.x sets `disableHostCheck: !proxy`, and this app declares no +# `proxy` in package.json, so webpack-dev-server accepts the preview hostname. +# Verified during bootstrap with a preview-style Host header (HTTP 200, no +# "Invalid Host header"). +CMD ["sh", "-c", "HOST=\"$CODEPRESS_BIND_HOST\" WDS_SOCKET_PORT=\"$CODEPRESS_HMR_CLIENT_PORT\" exec yarn start"] diff --git a/.codepress/dev-server/recipe.json b/.codepress/dev-server/recipe.json new file mode 100644 index 0000000..9ad76a7 --- /dev/null +++ b/.codepress/dev-server/recipe.json @@ -0,0 +1,22 @@ +{ + "schema_version": 1, + "bootstrapped_at": "2026-07-28T06:34:42Z", + "discovery_branch": "master", + "frontends": [ + { + "label": "web", + "working_dir": "web", + "dockerfile_path": ".codepress/dev-server/Dockerfile.web", + "dev_command": "sh -c 'HOST=\"$CODEPRESS_BIND_HOST\" WDS_SOCKET_PORT=\"$CODEPRESS_HMR_CLIENT_PORT\" exec yarn start'", + "prebuild_command": "", + "prebuild_inputs": [], + "framework": "cra", + "package_manager": "yarn", + "install_command": "yarn install --frozen-lockfile", + "dependency_manifests": ["web/yarn.lock"], + "dev_port": 3000, + "system_packages": ["procps"], + "size": "medium" + } + ] +}