Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Run Karma in a container with Angular’s non-interactive command ng test --no-watch --no-progress --browsers=ChromeHeadless. The image must contain your locked Node dependencies and a discoverable Chrome or Chromium executable. Configure the launcher only as far as your repository requires, and treat flags such as --no-sandbox and --disable-dev-shm-usage as environment-specific trade-offs rather than default boilerplate.
Confirm that the workspace uses Karma
New Angular projects currently default to Vitest, while Karma remains supported. Before changing Docker or browser settings, inspect the repository’s Angular CLI version, angular.json, and test target. The current ng test command supports both Karma and Vitest runners.
Inspect the test target
cat angular.json
node --version
npx ng version
Look for a test target configured with Karma (the current Angular Karma guide uses a runner: "karma" option). Match the builder and option shape already present in your workspace; configurations from another Angular generation may not be interchangeable. In a multi-project workspace, identify the project name so the container can run only the intended target.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteThe CI command
Run this from the workspace root:
ng test --no-watch --no-progress --browsers=ChromeHeadless
--no-watchexits after the test run instead of waiting for file changes.--no-progresskeeps progress-bar output out of CI logs.--browsers=ChromeHeadlessselects Karma’s headless Chrome launcher.
For one project in a multi-project workspace, append its name, for example ng test web-app --no-watch --no-progress --browsers=ChromeHeadless. Use the exact project identifier from angular.json.
#1 Best Overall
Choose how the container gets Chrome
Karma’s Chrome launcher can run Chrome or Chromium, including ChromeHeadless and ChromiumHeadless. Your image therefore needs a browser binary and a launcher that can discover it, or an explicit executable path.
System browser in the image
Installing the distribution’s Chrome or Chromium package keeps browser ownership visible in the Dockerfile. The package name and repository differ by base image, so pin the command to the Node/Linux combination your project already supports. Verify the resulting binary during the image build:
RUN command -v google-chrome || command -v chromium || command -v chromium-browser
This route can produce a smaller dependency graph than a second browser installer, but updates are tied to your operating-system package source.
Recommended Free Tools
Puppeteer-managed Chromium
Karma’s launcher documentation describes Puppeteer as one way to install Chromium for CI. It gives the project a browser-installation strategy that can be pinned alongside JavaScript dependencies, but downloads increase build time and image size. Keep the Puppeteer version and browser revision under the same lockfile policy as the application, and expose the installed executable to Karma if automatic discovery does not find it.
Neither approach is universally best. Decide using executable discovery, version pinning, update ownership, image size, build duration, and compatibility with the selected base image.
A version-aware Docker pattern
There is no single universal Dockerfile: Angular and Node compatibility, package manager, Linux distribution, and browser source all matter. The following pattern separates dependency installation, browser verification, and test execution. Replace the base image and browser-install step with versions approved by your repository.
FROM node:20-bookworm
WORKDIR /workspace
# Copy lockfiles first for repeatable, cacheable dependency installation.
COPY package.json package-lock.json ./
RUN npm ci
# Install Chrome or Chromium using the method selected for this image.
# Keep this step pinned to your distribution's documented package source.
# RUN apt-get update && apt-get install -y --no-install-recommends chromium
COPY . .
# Fail the build if no browser executable is present.
RUN command -v google-chrome || command -v chromium || command -v chromium-browser
CMD ["npx", "ng", "test", "--no-watch", "--no-progress", "--browsers=ChromeHeadless"]
If your project uses Yarn or pnpm, copy its lockfile and use the corresponding frozen-install command. Do not silently replace npm ci with a non-lockfile install in CI.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteMake Karma find the executable
First check the path inside the running image:
docker run --rm your-angular-test-image sh -lc 'command -v google-chrome || command -v chromium || command -v chromium-browser'
If the launcher cannot discover the binary, configure the path using the Karma launcher options already supported by your workspace, or set the browser environment variable expected by the launcher version you use. Keep that setting in source control so local and CI runs use the same definition. A custom launcher is appropriate when you need a controlled executable or additional flags; do not copy every flag from an example.
Rank #3
Sandbox and shared-memory settings
--no-sandbox
Chrome documentation describes --no-sandbox as sometimes used with headless mode but not recommended. Use it only when your container’s user or runtime setup genuinely requires it. If you must use it, isolate the CI job, avoid running untrusted workloads in the same container, and record the reason in the launcher configuration.
/dev/shm and --disable-dev-shm-usage
Chrome can crash or disconnect when the container’s shared-memory area is too small. Docker lets you increase it at runtime:
docker run --rm --shm-size=2g your-angular-test-image
Alternatively, Chrome’s --disable-dev-shm-usage flag makes the browser use another storage path. That can avoid a small shared-memory limit but may change I/O behavior. Inspect browser and container logs first, then adjust one relevant setting and retry; do not add both changes blindly.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Run locally and in CI
Build and execute
docker build -t angular-karma-ci .
docker run --rm --shm-size=2g angular-karma-ci
Use the same command in your CI job. Keep the workspace root as the working directory, preserve the lockfile, and publish the test exit code. A nonzero code should fail the pipeline.
Interactive diagnosis
When a run fails, open a shell in the image and check versions, paths, permissions, and memory limits:
docker run --rm -it --entrypoint sh angular-karma-ci
node --version
npx ng version
command -v google-chrome || command -v chromium || command -v chromium-browser
npx ng test --no-watch --no-progress --browsers=ChromeHeadless
For browser-level debugging, reproduce interactively where possible and retain Karma, Chrome, and container logs. Angular’s Karma guidance also recommends opening a test in the browser and using Chrome DevTools to inspect it and set breakpoints; a containerized reproduction may require forwarding a display or temporarily running an equivalent non-headless diagnostic environment.
Troubleshooting
“Chrome is not registered” or no browser launches
- Cause: Chrome/Chromium is absent, not executable, or outside the launcher’s search path.
- Fix: Run
command -vinside the image, confirm file permissions, and configure the launcher with the discovered path. Ensure the selected browser name matches the launcher installed by your Karma packages.
The process waits forever
- Cause: Watch mode is still enabled or the wrong project target was selected.
- Fix: Use
--no-watch, include--no-progress, and pass the project name when required.
Chrome starts and then disconnects
- Cause: Resource pressure, especially a small
/dev/shm, or an incompatible browser/runtime combination. - Fix: Inspect container limits and logs; retry with a larger
--shm-size. If the evidence points to shared-memory exhaustion, test--disable-dev-shm-usageinstead. Also verify that Node, Angular, Karma, and browser versions match the repository’s supported combination.
Tests fail only in the container
- Cause: Missing system libraries, different timezone or locale, unavailable network resources, or environment-dependent application code.
- Fix: Compare the container environment with local execution, log the browser’s stderr, and make required test data deterministic. Do not mask failures with broad flags such as
--disable-web-security.
The image build is slow or unexpectedly large
- Cause: Puppeteer downloading Chromium on every uncached build, or package layers invalidated by copying source before lockfiles.
- Fix: Copy lockfiles and run the frozen install before application source, cache dependency layers in CI, and pin the browser-installation strategy.
Reliability and maintenance checklist
- Record the Angular CLI, Node, Karma, launcher, and browser versions used by CI.
- Use the repository’s lockfile and a repeatable browser source.
- Verify the executable during image build rather than discovering its absence after deployment.
- Allocate enough shared memory for the workload and monitor disconnect or crash logs.
- Add only flags justified by an observed failure; avoid weakening browser security by habit.
- Rebuild deliberately when browser security updates are needed, and review the resulting test logs.
Or skip the browser setup
If your goal is to capture a rendered page rather than run Angular unit tests, ScreenshotNeo provides a website screenshot API and MCP server. One request returns PNG, JPEG, WebP, or PDF, while its capture flow accepts consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the shot. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →For a direct capture, see the ScreenshotNeo API documentation:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The same endpoint from Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
And Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Every plan includes the features; 1,000 screenshots per month are free without a card, and paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
Best Value
- Docker, Docker Swarm, Docker Compose, Programmer, Developer, Coding, Programming, Software Engineer, Code, DevOps, Deploy, Deployment, Kubernetes, Salt, Puppet, Chef, Terraform, Container, AWS, Azure, Cloud, Geek, Funny, Computer, Software, Tech, IT
- Integration, Scrum, Compile, Compilation, Science, Bug, Debug, Python, Linux, Java, Javascript, Scala, Dotnet, Kotlin
- Lightweight, Classic fit, Double-needle sleeve and bottom hem
Frequently Asked Questions
Can I use Chromium instead of Google Chrome?
Yes. Karma supports Chromium launchers, including ChromiumHeadless. Install a Chromium executable and select the matching launcher name, or configure its path explicitly.
Should I always add –no-sandbox in Docker?
No. Chrome documentation says the option is not recommended. Add it only when your container security model requires it, and isolate that CI workload.
Free tools Windows power users keep installed
One-click scans. No signup required.
Which is better for CI: a system browser or Puppeteer Chromium?
Neither is universally superior. Compare executable discovery, version pinning, update ownership, image size, build time, and compatibility with your base image.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

