5 Commits
Author SHA1 Message Date
Juan DenisandClaude Opus 5 0eeb187365 fix(buildpack): stop browser-driver postinstalls from filling the build disk
The generated Node Dockerfile installs the full dependency set when the plan
has a build command, because vite/tsc/webpack are devDependencies. That is
correct, but it also runs the postinstall of any browser driver in the tree:
puppeteer alone downloads ~500MB of Chrome into the build layer.

On a 25GB host that is the difference between a build that exports and one
that dies with "no space left on device" while unpacking the image -- the
observed failure fetched .cache/puppeteer/chrome/linux-145/... for a static
vite site whose runtime is `serve -s dist`.

Export the three standard opt-outs before `npm install`. The packages still
install (nothing else changes); only their browser binaries are skipped, and
no production build drives a browser.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 00:05:21 -04:00
Juan DenisandClaude Opus 5 ebb53d8fcc fix(buildpack): serve vite builds with a host-agnostic static server
`vite preview` host-checks every request against `preview.allowedHosts`
and blocks any domain the repo's vite config doesn't list -- the deployed
container answered localhost probes fine and refused every request the
panel proxy forwarded ("Blocked request. This host ... is not allowed").
Preview is a dev convenience, not a production server, per vite's own docs.

The vite default start command is now `serve -s dist -l tcp://0.0.0.0:4173`
(SPA fallback, no host check); the generator preinstalls serve globally
when the start command needs it, since the repo never declares it. A
repo-authored start script still wins and gets no serve install.

The @docker_builds leg now sends a foreign `Host:` header to every booted
container -- the localhost-only probe was exactly the blind spot that let
this class through.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 08:31:34 -04:00
Juan DenisandClaude Opus 5 20bfcd4947 test(buildpack): run generated Dockerfiles through the real docker daemon
test_buildpacks.py asserts on Dockerfile TEXT, which cannot see a bug that
only fails at build or boot time -- the `--omit=dev` dead fallback shipped
`vite: not found` to a user's deploy. New @docker_builds leg (gated on
SERVERKIT_DOCKER_BUILDS=1, sibling of @real_binaries) runs the full path
per stack: detect() -> generate_dockerfile() -> `docker build` ->
`docker run` -> HTTP 200. Fixtures: vite (the regression), express with no
build step (prod-only install must still boot), flask, static. Wired as a
backend-ci job beside real-binaries.

Writing the flask fixture surfaced the same dead-at-boot class one layer
up: detection invents `gunicorn app:app` / `uvicorn main:app` as the start
command but never installed the server, so a repo that doesn't declare
gunicorn built green and died at boot. The build command now installs the
invented server (a no-op when the repo already pins it); Procfile-authored
start commands remain the author's contract.

All four stacks verified locally: build + boot + HTTP 200 in 53s.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 01:58:57 -04:00
Juan DenisandClaude Opus 5 4c95a7da9f fix(buildpack): keep devDependencies when a node app has a build step
The generated node Dockerfile ran `npm install --omit=dev || npm install`.
`--omit=dev` exits 0, so the fallback never fired and `npm run build` died
with `vite: not found` -- build tooling (vite, tsc, webpack) is a
devDependency, and so is the server behind preview-style start commands.

Install the full dependency set whenever a build command exists, and put
node_modules/.bin on PATH so locally installed CLIs resolve in both RUN and
CMD. Apps with no build step still install production-only.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 01:48:02 -04:00
Juan DenisandClaude Opus 4.8 a550f16baf feat: Phase 2 developer experience — build packs, config snapshots, catalog certification
- Build packs / zero-Dockerfile deploys (C1): new BuildpackService detects the
  stack from a cloned repo (Node/Python/Go/PHP/Ruby/Rust/static), produces a
  transparent build plan and a generated Dockerfile, and persists the plan +
  overrides on the Application. POST /api/v1/buildpacks/{detect,generate}; a
  BuildpackPreview shows the detected plan + editable overrides + Dockerfile in
  the create wizard and the app Build tab. Builds on the existing build_method
  plumbing instead of duplicating it.

- Deployment config snapshots + diff engine (C4): ConfigurationService captures
  an immutable, hashed snapshot of resolved config (env keys + masked values,
  domains, image/tag, build method, volumes) at every deploy and rollback; new
  DeploymentSnapshot model + /api/v1/apps/<id>/snapshots[/diff|/restore]. A
  DeploymentTimeline + ConfigDiffModal surface "what changed" and one-click
  restore in the app Deploy tab. Secret values are never serialized.

- Template catalog certification (C5 cont.): a whole-catalog validation test
  proves all 105 declarative templates conform to the documented schema; fixed
  the stale index.json (was 63/105 entries) to list every bundled template.

Migration 030 adds the buildpack columns + deployment_snapshots table. Full
backend suite: 820 passed, 14 skipped; frontend builds clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 18:49:04 -04:00