Install the regular Google Chrome Stable package, then launch that same binary with the --headless flag. Headless Chrome is not a separate Ubuntu package in the current implementation. On a typical 64-bit Ubuntu 24 system, run the documented APT setup, verify the executable, and use Chrome’s command-line capture options for DOM output, screenshots, or PDFs.
What “Headless Chrome” means on Ubuntu 24
Current Headless mode is part of the normal Chrome browser. Chrome creates the browser’s platform windows but does not display them, so automation can run on a server or terminal without a desktop session. The unified implementation uses the regular Chrome code path and browser features.
Chrome 112 introduced this unified behavior. Since Chrome 132.0.6793.0, the older implementation is distributed separately as chrome-headless-shell. For ordinary automation, page rendering, screenshots, DOM extraction, and PDF generation, install Chrome Stable and use --headless.
Before you install
- Use a 64-bit Ubuntu 24 installation for the repository command shown below; Google’s example explicitly registers the
amd64architecture. - Have an account with
sudopermission and network access to Google’s package repository. - Do not assume a GPU, Vulkan stack, Node.js, Puppeteer, or D-Bus is required. Those are workload- or environment-specific dependencies, not prerequisites for the basic command-line mode.
- Keep enough disk space for the Chrome package, its dependencies, and the pages or PDFs your jobs create.
Install Google Chrome Stable from APT
The following sequence imports Google’s signing key, adds the stable repository, refreshes package metadata, and installs the regular browser package. Run each command in a terminal:
#1 Best Overall
curl -fsSL https://dl.google.com/linux/linux_signing_key.pub | sudo gpg --dearmor -o /usr/share/keyrings/googlechrom-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/googlechrom-keyring.gpg] http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee /etc/apt/sources.list.d/google-chrome.list
sudo apt update
sudo apt install -y google-chrome-stable
The repository line is written for amd64. If you are using a different architecture or an Ubuntu derivative, stop and confirm that Google’s package is available for that platform rather than blindly reusing the line.
Verify the installation and start Headless mode
Check the executable and version
command -v google-chrome-stable
google-chrome-stable --version
A successful installation prints the executable path and a Chrome version. The package itself is still a normal browser; Headless is enabled only when you pass the launch flag.
Launch without a visible window
google-chrome-stable --headless
For a useful operation, append a URL and one of Chrome’s capture flags. On systems where the executable is named google-chrome, use that name consistently instead.
Useful Headless command-line jobs
Print the rendered DOM
google-chrome-stable --headless --dump-dom https://example.com
--dump-dom outputs the serialized DOM after Chrome has parsed the document and run page scripts. That is different from downloading raw HTML with curl: client-side JavaScript can change what Chrome emits.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Capture a screenshot
google-chrome-stable --headless --screenshot --window-size=1280,900 https://example.com
Chrome writes screenshot.png in the current directory by default. --window-size=1280,900 sets the viewport used for the capture; change both numbers to match the layout you need.
Rank #2
Print a page to PDF
google-chrome-stable --headless --print-to-pdf=page.pdf https://example.com
The explicit filename is page.pdf. Without a filename, Chrome’s documented default is output.pdf.
Control waiting and timers
google-chrome-stable --headless --timeout=10000 --screenshot https://example.com
google-chrome-stable --headless --virtual-time-budget=5000 --dump-dom https://example.com
--timeout limits how long a capture command waits. --virtual-time-budget gives page code that depends on timers a bounded period of virtual time before Chrome proceeds. Choose values based on the page’s actual loading behavior; neither option guarantees that a slow API or an indefinitely running script will finish.
Access Chrome-internal URLs
For chrome:// targets, Chrome 123 and later require the --allow-chrome-scheme-url flag. This requirement applies to those internal URLs, not ordinary web pages.
google-chrome-stable --headless --allow-chrome-scheme-url chrome://gpu
Unified Headless Chrome versus chrome-headless-shell
| Option | What it is | Typical acquisition | When to choose it |
|---|---|---|---|
Regular Chrome with --headless |
Current Chrome implementation with the browser’s normal feature coverage, running without visible UI | Google Chrome Stable APT package | General automation, DOM output, screenshots, PDFs, and behavior that should match Chrome |
chrome-headless-shell |
Separate, older lightweight Headless implementation | Chrome for Testing distribution; legacy documentation shows npx @puppeteer/browsers install chrome-headless-shell@stable or a selected version |
Only when a task specifically requires the shell’s lighter behavior or its separate binary |
The shell is not an alternate executable name for the APT-installed browser. It follows a different download path and should not be installed merely because you want to hide Chrome’s window.
Security and server-environment considerations
Do not make --no-sandbox your default
Some specialized GPU or Colab examples launch Chrome with --no-sandbox. That flag disables Chrome’s security sandbox. The example’s environment does not establish that ordinary Ubuntu desktop or server installations need it.
Rank #3
Start without the flag. If an isolated container genuinely prevents the sandbox from starting, investigate the container’s user, namespaces, permissions, and profile configuration first. Use an explicit risk assessment before disabling a security control, and never copy a GPU demonstration’s complete command into a general server setup without understanding each option.
GPU, Vulkan and D-Bus are conditional
A GPU-oriented workload may need drivers, Vulkan settings, or a D-Bus service. Those steps belong to that workload’s environment. Basic Headless screenshots, DOM extraction, and PDF printing do not acquire those requirements from the installation commands above.
Recommended Free Tools
Use a writable profile for concurrent jobs
When running multiple jobs under the same Unix account, give each process an isolated temporary profile and output directory. A profile prevents simultaneous processes from fighting over locks or state:
profile=$(mktemp -d)
out=$(mktemp -d)
google-chrome-stable --headless --user-data-dir="$profile" --screenshot="$out/page.png" https://example.com
rm -rf "$profile" "$out"
Retain the output directory instead of deleting it when you need to inspect the result. In production, also clean abandoned temporary profiles after crashes.
Troubleshooting common failures
google-chrome-stable: command not found
Confirm that sudo apt install -y google-chrome-stable completed successfully, then run command -v google-chrome-stable. If your package exposes google-chrome instead, use that executable in every command.
Rank #4
APT reports a repository, key, or signature error
Check that the key file exists at /usr/share/keyrings/googlechrom-keyring.gpg, that the repository line points to the same file with signed-by=, and that the system clock and network connection are correct. Run sudo apt update again and read the first specific error rather than suppressing it.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsThe process exits immediately in a server or container
Run a minimal test with a known URL and capture stderr. Check file permissions, available shared memory, and whether another process is using the same profile. Add a unique --user-data-dir. Do not jump straight to --no-sandbox; determine whether the environment itself is blocking the sandbox.
The screenshot is blank or incomplete
Verify the URL from the same machine, allow enough wait time for the page, and test with --dump-dom. A page that depends on delayed JavaScript, authentication, geolocation, or a consent interaction may need a browser automation layer rather than a single CLI invocation. A fixed --virtual-time-budget can help timer-driven pages, but it cannot solve a failed network request.
chrome:// access is denied
On Chrome 123 and later, include --allow-chrome-scheme-url for internal Chrome URLs. Ordinary HTTPS pages do not need this flag.
Several jobs interfere with one another
Use a separate --user-data-dir, output filename, and temporary workspace for each process. Avoid writing every job to the default screenshot.png or output.pdf, which can cause overwrites even when Chrome itself starts correctly.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Best Value
Or skip the browser setup
If your goal is an image or PDF rather than operating Chrome locally, ScreenshotNeo provides a website screenshot API and MCP server. It accepts one GET request and returns PNG, JPEG, WebP, or PDF output. Before capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled.
Only clean shots are billed. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
One-call examples
See the complete parameter reference in the ScreenshotNeo documentation. Replace YOUR_API_KEY and the example URL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Every feature is available on every plan. The Free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
FAQ
Is Headless Chrome a different package from Google Chrome?
No. For current Chrome, Headless is a launch mode of the regular browser. The separately distributed chrome-headless-shell is the legacy implementation, not a required companion package.
Can I use these commands on an Ubuntu desktop?
Yes, provided the package and repository architecture match your system. Headless suppresses the visible browser window, while the same Chrome installation can still be launched normally when you omit the flag.
What does --dump-dom provide that curl does not?
It reports the serialized DOM after Chrome has parsed the page and executed its scripts, whereas curl retrieves the server response without running browser JavaScript.
Frequently Asked Questions
Does Headless mode require an X server or desktop environment?
The purpose of Headless mode is to run Chrome without visible UI; a desktop display is not part of the basic invocation.
Free tools Windows power users keep installed
One-click scans. No signup required.
When should I install chrome-headless-shell instead?
Choose it only when a tool specifically requires the older lightweight shell implementation or its separate Chrome for Testing distribution.
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.




