Bootstrap CodePress Live Dev Server recipe + dev Dockerfiles - #51
Open
codepress-dev[bot] wants to merge 1 commit into
Open
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 inserver/. 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.json—schema_version: 1with a singlewebfrontend entry:working_dir: "web",framework: "cra",package_manager: "yarn"(fromweb/yarn.lock; nopackageManagerfield),install_command: "yarn install --frozen-lockfile",dependency_manifests: ["web/yarn.lock"],dev_port: 3000,system_packages: ["procps"],size: "medium". Noprebuild_command—web/package.json'sstartscript is a plainreact-scripts startwith no build prefix orpredevhook.Dockerfile.web— thin, dev-mode, toolchain-only: nonode_modulesbaked, no sourceCOPY, no CodePress binary. Deps are provided at runtime against the bind-mounted checkout.The one judgement call worth reviewing is the
node:16-bookwormbase.web/yarn.lockresolvesreact-scripts@1.0.10→webpack@2.6.1/webpack-dev-server@2.5.0, against React 15 — a 2017-era toolchain. The repo pins no Node version (no.nvmrc, noengines.node), so defaulting to current LTS risked an image whose dev server never boots.react-scripts@1.0.10declaresengines: {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. Upgradingreact-scriptswould 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.jssetsdisableHostCheck: !proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true'.web/package.jsondeclares noproxy, so the host check is already off; the env var in theCMDis a guard for if aproxyfield is ever added, which would otherwise start rejecting the previewHostheader.scripts/start.jsreadsprocess.env.HOSTandprocess.env.PORT, so the bind address stays runtime-driven viaCODEPRESS_BIND_HOST— nolocalhost/127.0.0.1literal anywhere in the image.react-dev-utils@3.0.2/webpackHotDevClient.jsbuilds its SockJS URL fromwindow.location(protocol/hostname/port), so HMR rides the preview origin and works behind the proxy given websocket upgrades.WDS_SOCKET_PORTdoes not exist in this version — it is set as a harmless no-op that becomes correct ifreact-scriptsis upgraded, and the comment says so.Why no
staging_backend_url: there is no.env.staging,.env.example,vercel.json,next/viteconfig,.github/workflows/, or.codepress/verify-staging/recipe.jsonin 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), andweb/srcreads no API-base env var to prefill anyway.Why no preview-CORS edit on
server/: the Django backend does have API routes (/api/auth/viarest_auth), but it fails the cross-origin gate on both signals. It configures no CORS whatsoever —django-cors-headersis not inINSTALLED_APPS,MIDDLEWARE, orPipfile— andweb/srcmakes zero HTTP calls (nofetch, noaxios, no absolute API base URL). The architecture is explicitly same-origin:web/package.json'spostbuildcopies the CRA build intoserver/static/build/,TEMPLATES.DIRSpoints there, andserver/urls.pyends with a catch-allurl(r'^', index_views.index)servingindex.htmlfor 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.pyis a single module withDEBUG = 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
.codepress/dev-server/recipe.json— schema_version 1, onewebfrontend entry (CRA, yarn, port 3000).codepress/dev-server/Dockerfile.web— thin dev-mode image onnode:16-bookworm, binds viaCODEPRESS_BIND_HOST, wires HMR to theCODEPRESS_HMR_*env vars, installsprocps, bakes no deps or sourceTest plan
.codepress/dev-server/and modifies nothing else:git diff --stat origin/master...HEADpython3 -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'])"→ expect1 web 3000, and confirmdev_port3000 matches CRA's default forweb/package.json'sstartscriptdocker build -f .codepress/dev-server/Dockerfile.web -t drx-web-dev .— expect a successful build andyarn --versionto resolve during itweb/src/containers/home/Home.jsand confirm the browser updates without a manual refresh (HMR rides the preview origin via SockJS)docker run --rm -p 3000:3000 -v "$PWD:/app" drx-web-devafter ayarn installinweb/, thencurl -I http://localhost:3000→ expect HTTP 200 and no 'Invalid Host header' in the logsOpen items
node:16-bookwormbase tag was confirmed to exist on thepublic.ecr.aws/docker/librarymirror, and the HMR/bind/host-check behavior was verified by reading the pinnedreact-scripts@1.0.10andreact-dev-utils@3.0.2sources, but the first real build/boot is unverified. The first preview claim is the actual test.node:16-bookwormis EOL and pinned deliberately (see technical details). Ifweb/'sreact-scriptsis ever upgraded, bump this base to current LTS and drop theDANGEROUSLY_DISABLE_HOST_CHECKguard —WDS_SOCKET_PORTin the CMD then starts doing real work.yarn install --frozen-lockfileagainst 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.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-headersas a dependency,corsheaders.middleware.CorsMiddlewareaboveCommonMiddleware, andCORS_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 nopackage.jsonand are not imported byweb/src, so they are not a runnable frontend and no social-auth preview wiring was applied. If that flow is ever wired intoweb/, preview sign-in will need the relay callback registered with the provider.Authors
Generated with CodePress