Skip to content

fix(docker): include Playwright headless shell#2067

Open
reallav0 wants to merge 2 commits into
unclecode:developfrom
reallav0:agent/include-playwright-headless-shell
Open

fix(docker): include Playwright headless shell#2067
reallav0 wants to merge 2 commits into
unclecode:developfrom
reallav0:agent/include-playwright-headless-shell

Conversation

@reallav0

Copy link
Copy Markdown

Summary

  • copy Playwright's chromium_headless_shell-* cache into the runtime user's cache
  • add a Dockerfile regression check for both Chromium artifacts

Root cause

The image runs as appuser, but only copied the full Chromium cache from root. Headless crawls resolve chromium_headless_shell-*, so the Docker server exited at startup when that directory was missing.

Fixes #2064.

Validation

  • git diff --check
  • standard-library Dockerfile regression check passed

Not run: Docker image build (Docker daemon unavailable); focused pytest could not be installed because the full project dependency set exhausted available disk space.

Comment thread deploy/docker/tests/test_security_container_posture.py Outdated

@SohamKukreti SohamKukreti left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quick fix! I dug into #2064 independently and can confirm both the root cause and that this fix works — verified against the published images.

Root cause (confirmed):

  • playwright install --with-deps installs two Chromium artifacts in root's cache: chromium-1228 and chromium_headless_shell-1228. The old copy glob chromium-* (hyphen) never matched the underscore-named headless shell, so it's missing from appuser's cache in both the 0.9.0 and 0.9.1 images.
  • This was harmless until 0.9.1: commit c34ffc0 (#2051) stopped passing channel="chromium" for the default config, and with no channel, Playwright ≥1.49 launches headless mode with the headless shell — the one binary the runtime user never had. Boot crash → restart loop.

Fix verification: I injected chromium_headless_shell-1228 into /home/appuser/.cache/ms-playwright/ in a stock unclecode/crawl4ai:0.9.1 container (byte-for-byte what this PR's copy produces) and the container boots cleanly — Application startup complete, /health returns OK, and the permanent browser pool runs with a chrome-headless-shell process. Image size cost is +262 MB uncompressed (~7% on a ~3.9 GB image).

Two things this PR gets right that are worth preserving in review:

  • Keeping both binaries (not just the headless shell): full chromium-* is still required for headless=false requests — the image ships Xvfb precisely for headed mode. Copying only the shell would fix the boot crash but break headed crawls at request time.
  • Keeping cp rather than mv: crawl4ai-doctor runs as root after this line and needs root's copy intact.

One non-blocking nit on the test regex (inline). LGTM otherwise, happy to see this un-drafted and merged.

@reallav0 reallav0 marked this pull request as ready for review July 10, 2026 12: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