Skip to content

Slim public Chromium runtime package set#274

Merged
IlyaasK merged 4 commits into
mainfrom
hypeship/slim-public-runtime
Jun 26, 2026
Merged

Slim public Chromium runtime package set#274
IlyaasK merged 4 commits into
mainfrom
hypeship/slim-public-runtime

Conversation

@IlyaasK

@IlyaasK IlyaasK commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Summary

This is the public-repo equivalent of the private runtime slimming PR. It narrows the public Chromium runtime package install lists so the final headless/headful images stop carrying build-time tooling that is not used by the current runtime path.

What changed:

  • Headless final runtime image: remove build-essential, libssl-dev, git, and software-properties-common.
  • Headful final runtime image: remove the old Python/pyenv-style build block: build-essential, libssl-dev, zlib1g-dev, libbz2-dev, libreadline-dev, libsqlite3-dev, git, libncursesw5-dev, xz-utils, tk-dev, libxml2-dev, libxmlsec1-dev, libffi-dev, and liblzma-dev.
  • Headful final runtime image: remove the old add-apt-repository ppa:mozillateam/ppa flow and its software-properties-common dependency.
  • Headful final runtime image: remove python2 from the later runtime install block.
  • Both final runtime images: replace gpg-agent with gpg. The Envoy installer needs the gpg binary for gpg --dearmor; it does not need the agent package.

The net diff is only the two Dockerfiles.

Why

The image already uses multi-stage builds for native/Xorg/neko build inputs. Those build-stage dependencies stay where they are.

The packages removed here were still installed in the final runtime image, where they increase image size and runtime surface area without being referenced by the current launch/supervisor/API/browser path.

Git History / Removal Rationale

The package history points to old image lineage rather than current runtime requirements.

removed item why it appears to have been added why this PR removes it
build-essential, gcc, make Introduced in 5c71470 (WebRTC OSS launch, PR #13) under a Dockerfile comment labeled # Python/pyenv reqs. That commit moved the old unikraft/WebRTC image structure into images/chromium-*. Final runtime no longer builds Python or native modules. Native/Xorg/neko compilation remains isolated in builder stages.
libssl-dev, zlib1g-dev, libbz2-dev, libreadline-dev, libsqlite3-dev, libncursesw5-dev, tk-dev, libxml2-dev, libxmlsec1-dev, libffi-dev, liblzma-dev Added in the same # Python/pyenv reqs block from 5c71470. These are typical compile headers for Python/native dependency builds. They are development headers, not runtime browser/session packages. Current runtime paths use installed shared libraries and copied artifacts, not compile headers.
git Added with the old Python/build helper set in 5c71470, and also used in builder/release contexts elsewhere in the repo. The final image should not clone/build source at runtime. git remains available in builder contexts where it is actually referenced.
xz-utils Added in the old Python/pyenv block from 5c71470, likely to unpack source archives during legacy build flows. Runtime does not extract .tar.xz source archives. Downloader/build stages that need archive handling keep their own tools.
software-properties-common / add-apt-repository Added for old PPA install paths in 5c71470: ppa:mozillateam/ppa for headful and ppa:xtradeb/apps for Chromium in the older image path. Current Dockerfiles do not install Firefox or use those PPA flows in the final runtime package install. Keeping the PPA helper only preserves dead install machinery.
python2 Added in 5c71470 with the old WebRTC/neko/demo runtime setup. The remaining obvious Python script path is the legacy headful demo payload handled separately. Current public runtime startup is Go wrapper/API + supervised services; no current runtime entrypoint requires Python 2.
gpg-agent Added later during apt/key setup work, but the actual needed binary is gpg. This PR keeps gpg because shared/envoy/install-proxy.sh runs gpg --dearmor, and removes only the agent package.

Measured Impact

Controlled local builds were run with --no-cache and unique cache IDs during the split work.

image before after size delta cold build
public headless 1985.2 MB 1738.1 MB -247.1 MB 196s -> 173s
public headful 2695.0 MB 2329.3 MB -365.7 MB 347s -> 268s
private headless 1975.6 MB 1717.1 MB -258.5 MB 182s -> 183s
private headful 2674.0 MB 2296.9 MB -377.1 MB 332s -> 318s

Exact final public numbers can shift slightly because this branch intentionally keeps gpg after the Envoy installer dependency was confirmed.

Validation

Ran locally after merging current main into this branch:

  • git diff --check origin/main...HEAD
  • DOCKER_BUILDKIT=1 docker build --check -f images/chromium-headless/image/Dockerfile .
  • DOCKER_BUILDKIT=1 docker build --check -f images/chromium-headful/Dockerfile .
  • cd server && go test ./e2e -run TestDoesNotExist -count=0
  • ~/.agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main --prompt-file /tmp/pr274-review-notes.md

Autoreview note:

  • Rejected the Firefox/PPA warning as not applicable after verifying the branch does not install a firefox package. The relevant userland install block contains x11-apps, tint2, wget, xdg-utils, libvulkan1, fontconfig, and unzip; the image uses the copied Kernel Chromium browser. The final autoreview rerun with that evidence was clean.

GitHub Actions on the current-main refresh:

  • image builds: passed
  • server test/e2e job: passed
  • launcher test, scan, and Socket: passed

Unknowns / Final Gates

  • The remaining product question is whether final runtime images are expected to support arbitrary user process-exec workloads that require git, compilers, Python 2, xz, or development headers. The current repo/runtime paths do not show that dependency, but that is still the compatibility decision to make before merging.
  • Full image CI passed on the current-main refresh.

Fast Docker Review

This PR follows the fast-build guidance by keeping build-only packages out of the final runtime image. The Xorg/neko/native build inputs stay in builder stages; the runtime stage only keeps packages needed by the current browser/session path.

Against the checklist:

  • Build tools and development headers are removed from final images instead of being shipped to runtime.
  • Existing multi-stage build boundaries stay intact; compiled artifacts are still copied from builder stages.
  • Stable dependency work remains before volatile application source in the Dockerfiles.
  • No new broad COPY statements or early source copies are added.
  • gpg stays because the Envoy install step actually needs the gpg binary; gpg-agent does not stay just because it used to be adjacent.

Note

Low Risk
Docker-only runtime package list changes with no app code edits; main risk is breaking workloads that relied on compilers, git, or Python 2 inside the final image.

Overview
Narrows final-runtime apt installs in the public headless and headful Chromium Dockerfiles so images stop shipping legacy build/PPA tooling that the current Go wrapper, supervisor, and Chrome-for-Testing path does not use.

Headless drops build-essential, libssl-dev, git, and software-properties-common from the main runtime package block. Headful removes the old # Python/pyenv reqs compile-header set, git, xz-utils, the Mozilla PPA (software-properties-common + add-apt-repository), and python2 from the later runtime install. Both swap gpg-agent for gpg, which shared/envoy/install-proxy.sh needs for gpg --dearmor during Envoy setup.

Multi-stage builders (e.g. xorg-deps, ffmpeg-downloader) are unchanged; only what lands in the shipped runtime layer is trimmed, with reported image size and cold-build time reductions.

Reviewed by Cursor Bugbot for commit 7182ebf. Bugbot is set up for automated code reviews on this repo. Configure here.

@IlyaasK IlyaasK requested a review from sjmiller609 June 4, 2026 14:37
@IlyaasK IlyaasK marked this pull request as ready for review June 25, 2026 18:31
IlyaasK added a commit that referenced this pull request Jun 26, 2026
## Summary

Port the public-safe parts of the merged private server e2e
speedup/stability work into one public PR.

What changed:
- split the public server workflow into `test-server-unit` and
`test-server-e2e`
- keep Go build caching on the unit job only and install Playwright
dependencies explicitly before e2e
- force Docker-backed e2e container teardown instead of waiting for
graceful test-container stop
- add e2e container lifecycle timing logs for start/stop/readiness
profiling
- replace fixed sleeps in enterprise extension and MV3 tests with
bounded condition waits
- make Playwright daemon recovery wait on DevTools + execution recovery
instead of a fixed sleep
- isolate `cdpmonitor` subtests so they do not share monitor state
- parallelize public-safe configure, restart, and recording e2e cases
- replace external `example.com` / `google.com` transfer setup with
deterministic browser profile fixture state
- run recording audio analysis inside the already-running test container
instead of extra short-lived Docker runs

## Public/private scope

This intentionally ports only changes whose target files/tests already
exist in the public repo.

Skipped private-only work:
- private persistence e2e consolidation / cleanup speedups touched
`server/e2e/e2e_persist_login_test.go`, which does not exist in public
- no private-only tests or private image names are added here

## Why

The private test-speedup stack is merged and proved useful for
separating real image failures from unrelated e2e flakes. Public
currently has the same broad server e2e shape and several of the same
tests, so this PR brings the public suite up to parity without changing
production image/API behavior.

This follows the same testfast/startfast direction as the private work:
- remove fixed sleeps where the test can wait for a real condition
- keep assertions strict and failure-readable
- reduce short-lived container churn in tests
- separate unit and e2e workflow work without creating special one-test
shards
- keep profiling data visible in normal e2e logs

## Timing

Baseline is latest successful public `main` server workflow before this
PR: run `28205858762` on `5af656d`.
After is this PR's successful server workflow: run `28245446048` on
`bda8701`.

| metric | before | after | delta |
| --- | ---: | ---: | ---: |
| server workflow wall | 17m33s | 7m29s | -10m04s |
| server test critical job wall | 11m16s single `test` job | 4m38s
`test-server-e2e` job | -6m38s |
| e2e package runtime | 522.015s | 203.792s | -318.223s |
| unit job availability | blocked behind image builds + e2e in single
job | 1m52s standalone `test-server-unit` | earlier signal |
| enterprise extension e2e | ~90.8s per image | 27.1s headless / 29.5s
headful | ~61s faster per image |
| configure powerset e2e | 98.9s | longest case 14.4s, suite 14.4s wall
| parallelized cases |
| restart timing e2e | 118.4s | 37.2s headful / 36.2s headless wall |
parallelized image cases |
| transfer fixture tests | 16.9s / 17.4s / 19.6s | 10.3s / 10.4s / 10.9s
| deterministic fixture |
| recording audio test | 23.1s | 17.5s | no extra analysis containers |

Image build timings are shown in validation but should not be treated as
the primary test-speedup signal because Docker cache state varies by
run. The most comparable signal is the e2e package runtime and the
server test critical path.

## Validation

Local:
- `git diff --check origin/main...HEAD`
- `yq '.' .github/workflows/server-test.yaml >/dev/null`
- `cd server && go test ./e2e -run
'TestExtensionDownloadObservedRequiresUpdateXMLAndCRX|TestExtensionDownloadLogSince'
-count=1`
- `cd server && go test ./lib/cdpmonitor -run TestBindingAndTimeline
-count=1`
- `cd server && go test ./e2e -run TestDoesNotExist -count=0`
- `cd server && make test-unit`
- `cd server/e2e/playwright && corepack pnpm install --frozen-lockfile`
- `cd server/e2e/playwright && corepack pnpm exec tsx index.ts`
(usage/parse check)
- `~/.agents/skills/autoreview/scripts/autoreview --mode local
--prompt-file /tmp/public-e2e-speedups-review-notes.md` clean

GitHub Actions on this PR:
- run `28245446048`: passed
  - `build-headful / docker`: 1m15s
  - `build-headless / docker`: 2m49s
  - `test-server-unit`: 1m52s
  - `test-server-e2e`: 4m38s
  - e2e package runtime: 203.792s
- launcher `test`: passed in 21s
- scan and Socket: passed

Notes:
- this package does not include `typescript`, so there is no local `tsc
--noEmit` gate to run

## Review notes

- test/workflow-only; no runtime image Dockerfiles or production API
handlers changed
- no test assertions are loosened; sleeps become bounded waits on the
same expected outcomes
- public image cleanup PRs #274 and #275 already have green checks and
Cursor Bugbot passing; they remain blocked only on review/merge policy

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Test and CI workflow changes only; assertions stay strict and
production runtime code is untouched. Main residual risk is heavier
parallel e2e load on CI runners, which this PR already exercised
successfully.
> 
> **Overview**
> Ports public-safe **server e2e speed and stability** work: faster
teardown, less fixed sleeping, clearer CI split, and more parallel safe
tests—without changing production images or API handlers.
> 
> **CI (`server-test.yaml`)** adds workflow **concurrency** (cancel
in-progress), splits the old combined job into **`test-server-unit`**
(`make test-unit`, Go cache on) and **`test-server-e2e`** (`make
test-e2e` after image builds, explicit **pnpm** PATH + Playwright
install, Go cache off).
> 
> **E2e harness** forces Docker container stop with **`StopTimeout(0)`**
and logs **`[e2e-timing]`** for start/stop and readiness phases.
> 
> **Flake reduction** replaces fixed sleeps with **bounded polls**:
enterprise extension (policy, download logs, `chrome://extensions`),
Playwright daemon recovery after Chromium restart (**`WaitDevTools`** +
retry), and MV3 service-worker checks in Playwright
(**`waitForFunction`**).
> 
> **Other test changes**: **`t.Parallel()`** on selected
configure/restart/recording cases; zip transfer bench uses a
**deterministic S3 fixture** instead of external sites; recording audio
analysis runs **ffmpeg/ffprobe inside the running container**;
**`cdpmonitor`** binding/timeline subtests each get an isolated monitor
via **`withMonitor`**.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
bda8701. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@IlyaasK IlyaasK merged commit 97ede05 into main Jun 26, 2026
11 checks passed
@IlyaasK IlyaasK deleted the hypeship/slim-public-runtime branch June 26, 2026 15:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants