diff --git a/.codepress/dev-server/Dockerfile.web b/.codepress/dev-server/Dockerfile.web new file mode 100644 index 0000000..a9ce5c8 --- /dev/null +++ b/.codepress/dev-server/Dockerfile.web @@ -0,0 +1,72 @@ +# 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 a HARD REQUIREMENT here, not a default choice. +# This app pins react-scripts 1.0.10 -> webpack-dev-server 2.5.0 -> sockjs -> +# websocket-driver@0.6.5, which calls process.binding('http_parser'). That +# internal binding was removed after Node 18, so on Node 20+ `react-scripts +# start` exits immediately with: +# Error: No such module: http_parser +# Verified empirically: Node 18.20.5 compiles and serves this app; Node 25 fails. +# Do not raise this base image without first upgrading react-scripts. +FROM public.ecr.aws/docker/library/node:18-bookworm + +# System packages the dev runtime needs. `procps` only: this app has no +# source-built native modules (its one native dep, fsevents, is darwin-only and +# optional), so no additional apt library is required. +RUN apt-get update \ + && apt-get install -y --no-install-recommends procps \ + && rm -rf /var/lib/apt/lists/* + +# Yarn 1 (this repo carries a v1 `web/yarn.lock` and declares no +# `packageManager` field, so enable Corepack without pinning a version). +RUN corepack enable + +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` in this image against the bind-mounted checkout). Only the +# toolchain lives here. + +# HMR + bind config. Values come from the runtime, never hardcoded. +# +# react-scripts 1.x reads HOST and PORT from the environment directly. Its HMR +# client (react-dev-utils/webpackHotDevClient) builds the SockJS URL from +# `window.location`, so the websocket rides the preview origin and needs no +# client-port flag — the same origin-based behaviour Next.js has. The +# CODEPRESS_HMR_* vars stay declared for the uniform runtime contract, and the +# CMD maps CODEPRESS_HMR_CLIENT_PORT into WDS_SOCKET_PORT so the wiring is +# already correct if react-scripts is ever upgraded (WDS_SOCKET_PORT is inert in +# 1.x). +# +# BROWSER=none stops react-scripts from trying to launch a browser in the +# container. DANGEROUSLY_DISABLE_HOST_CHECK=true is the CRA equivalent of Vite's +# `server.allowedHosts` — it keeps the preview hostname accepted by +# webpack-dev-server's host check. CRA 1.0.10 already disables that check while +# no `proxy` field is set in package.json; this makes the preview keep working if +# one is added later. +ENV HOSTNAME=0.0.0.0 \ + CODEPRESS_BIND_HOST=0.0.0.0 \ + PORT=3000 \ + CODEPRESS_HMR_CLIENT_PORT=443 \ + CODEPRESS_HMR_PROTOCOL=wss \ + BROWSER=none \ + DANGEROUSLY_DISABLE_HOST_CHECK=true + +WORKDIR /app/web +EXPOSE 3000 + +# Put the workspace bins on PATH so the dev command — and anything it shells out +# to — resolves node_modules/.bin even when a binary is invoked directly. These +# dirs are populated at run time on the bind-mounted checkout (hydration / +# runtime install). 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). Bind comes from CODEPRESS_BIND_HOST — the dedicated bind +# contract — rather than the ambient HOSTNAME, and is passed to react-scripts as +# HOST. Invoked through yarn rather than as a bare binary so it resolves without +# depending on PATH. +CMD ["sh", "-c", "HOST=\"${CODEPRESS_BIND_HOST:-0.0.0.0}\" WDS_SOCKET_PORT=\"${CODEPRESS_HMR_CLIENT_PORT:-443}\" yarn start"] diff --git a/.codepress/dev-server/recipe.json b/.codepress/dev-server/recipe.json new file mode 100644 index 0000000..c20db39 --- /dev/null +++ b/.codepress/dev-server/recipe.json @@ -0,0 +1,22 @@ +{ + "schema_version": 1, + "bootstrapped_at": "2026-07-26T00:29:14Z", + "discovery_branch": "master", + "frontends": [ + { + "label": "web", + "working_dir": "web", + "dockerfile_path": ".codepress/dev-server/Dockerfile.web", + "dev_command": "sh -c 'HOST=\"${CODEPRESS_BIND_HOST:-0.0.0.0}\" WDS_SOCKET_PORT=\"${CODEPRESS_HMR_CLIENT_PORT:-443}\" 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" + } + ] +}