You can run browser automation on Ubuntu without installing or opening a desktop environment: administer the server over SSH, install an automation framework and its browser dependencies, then launch the browser in headless mode. These are two separate meanings of “headless”: Ubuntu has no local graphical desktop, while the browser does not display a visible window. This guide covers the common Playwright and Puppeteer setups; exact package requirements and browser behavior depend on your Ubuntu release and framework version.
What “headless Ubuntu” means for browser automation
An Ubuntu Server host can be managed remotely through SSH without a monitor, keyboard, or desktop session. That does not determine how the browser runs. Playwright or Puppeteer can launch Chromium without showing a window, even though the operating system itself may have a graphical desktop.
For a typical server or CI job, you need an Ubuntu host with network access, a user account able to install the required software, SSH access for administration, and a supported version of Node.js for the framework commands below. You do not need to install a full desktop environment just to run a browser headlessly.
Prepare the Ubuntu host and connect securely
Choose the host and plan network access
Use an Ubuntu Server release appropriate for your environment and confirm its support status and package availability before deployment. Ubuntu’s documentation index lists Server guides for 26.04 LTS, 24.04 LTS, and 22.04 LTS, but that listing alone does not establish which release is right for every workload. On a physical board, decide how it will obtain an address before boot: static addressing, router discovery, or mDNS/Avahi are possible approaches. On a VM or cloud instance, use the address or discovery mechanism supplied by that environment.
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 →#1 Best Overall
Use SSH keys for remote administration
Configure SSH public-key access using the provisioning method for your host, then connect with its reachable address or hostname:
ssh ubuntu@HOST_OR_IP
Replace ubuntu and HOST_OR_IP with the account and address you actually configured. A .local hostname may resolve on a local network when mDNS/Avahi is available; it is not a universal replacement for a known IP address or router-managed discovery.
Canonical recommends leaving SSH password-based authentication disabled in its headless board setup documentation, because default credentials can be guessable. Keep the SSH account and host setup specific to your provisioning method rather than assuming every Ubuntu image uses the same username or authentication defaults.
Install Playwright and its Chromium dependencies
Playwright’s documented command installs Chromium and the Linux dependencies it lists for that Playwright release:
Recommended Free Tools
npm install --save-dev playwright
npx playwright install --with-deps chromium
Run the commands from your project directory. The first adds Playwright to the project; the second fetches its Chromium browser and installs required system dependencies. Browser and dependency requirements can change across Playwright versions, so use the documentation for the version you install when provisioning a reproducible host.
Rank #2
Choose which Chromium implementation to install
Playwright’s regular headless Chromium path uses a separate Chromium headless shell. If that is the implementation your workload needs, the documentation offers an install mode that downloads only the shell:
npx playwright install --with-deps --only-shell chromium
For the newer Chrome headless implementation, Playwright documents selecting the chromium channel. You can optionally use --no-shell at install time when you do not need the separate headless shell:
npx playwright install --with-deps --no-shell chromium
The mode matters when test fidelity is important. Playwright says its newer headless mode uses the real Chrome browser, while its standard headless route uses the separate shell. Branded Chrome and Edge are not installed by Playwright by default; they may be the better target for public-browser regression tests or codec-specific behavior. Chromium can be ahead of branded Stable releases, so choose based on the browser behavior you intend to test, not just the fact that both launch headlessly.
Run a small Playwright launch check
After installation, this Node.js script launches the default headless browser, opens a page, prints its title, and closes cleanly:
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
console.log(await page.title());
} finally {
await browser.close();
}
})();
Save it as check.js and run node check.js. The expected output is the page title, Example Domain. If launch fails before navigation, investigate browser installation, shared libraries, and sandbox configuration rather than assuming the remote host needs a desktop.
Rank #3
Install Puppeteer and its browser
Installing the puppeteer package normally downloads a compatible Chrome for Testing build and a chrome-headless-shell. The default browser cache is $HOME/.cache/puppeteer. Install it in the project:
npm install --save-dev puppeteer
Some package managers or configurations block dependency install scripts. If Puppeteer is present but its browser is missing, install the browser explicitly:
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchnpx puppeteer browsers install
Alternatively, configure your package manager to permit the Puppeteer install script. Package-manager controls and commands differ, so follow the relevant manager’s current instructions rather than copying a setting from another tool.
Use Puppeteer to verify headless launch
This script launches the browser Puppeteer installed, visits a page, prints the title, and closes the browser even if navigation fails:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
console.log(await page.title());
} finally {
await browser.close();
}
})();
Run it with node check.js; it should print Example Domain if launch and navigation succeed. Puppeteer’s puppeteer-core package does not download Chrome. Use it when you manage the browser separately or connect to a remote browser, and provide the appropriate browser configuration for that setup.
Rank #4
Keep the browser sandbox enabled
Do not reflexively add Chromium’s --no-sandbox flag to make a launch error disappear. Puppeteer strongly discourages running without a sandbox and recommends configuring one instead. Its documentation describes --no-sandbox only for cases where the opened content is absolutely trusted. A browser automation job may visit untrusted pages, so disabling this isolation can increase risk.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
If the browser reports a sandbox or user-namespace error, check the applicable Ubuntu and browser guidance first. Puppeteer documents an AppArmor interaction on Ubuntu 23.10 and later: an AppArmor profile may prevent downloaded Chrome for Testing binaries from using user namespaces. The relevant conditions and remedy are version-sensitive; consult the current Puppeteer troubleshooting instructions for the Ubuntu release and Chrome build in use.
Diagnose launch failures on Ubuntu
Browser executable is missing
- Symptom: Playwright or Puppeteer reports that the browser executable cannot be found.
- Likely cause: The browser installation step did not run, the package manager blocked Puppeteer’s install script, or the process is using a different home directory/cache than the installer.
- Fix: For Playwright, rerun the appropriate
npx playwright installcommand. For Puppeteer, runnpx puppeteer browsers installand check that the runtime user can read the configured browser cache.
Shared libraries are missing
- Symptom: The browser executable exists but exits at launch with a missing-library message.
- Likely cause: The host lacks a shared library required by that browser build.
- Fix: For Playwright, run its dependency-install command for the installed browser and framework version. For Puppeteer, inspect the browser’s dynamic dependencies; its troubleshooting documentation describes using
ldd chrome. Install the missing packages appropriate to the Ubuntu release and browser build, consulting the current Puppeteer list rather than relying on a package list copied from another release.
The libraries commonly involved in Debian/Ubuntu browser launches include NSS, GBM, GTK, font, X11, and Pango-related packages. That is a diagnostic category list, not a universal apt command: exact package names and requirements depend on the system and browser build.
Launch fails only under a service or CI account
- Symptom: A script works in an interactive SSH session but fails when run by a service, scheduler, or CI worker.
- Likely cause: The automation process uses a different user, home directory, environment, browser cache, or security policy.
- Fix: Run the installation and automation as the intended runtime user, verify that the browser cache is accessible to that user, and capture the full launch error from the service logs. Check sandbox and AppArmor behavior for that account rather than disabling browser isolation by default.
Tests behave differently from the target browser
- Symptom: A test passes with one headless browser but differs from a user-facing Chrome or Edge session.
- Likely cause: The test is using Chromium, a separate headless shell, or another browser version instead of the browser implementation it aims to represent.
- Fix: Select the documented Playwright channel or Puppeteer mode that matches the target. Record the framework and browser versions in CI, and verify behavior against the intended branded browser when that is the actual requirement.
Make the setup reproducible and reliable
Browser automation depends on more than the Ubuntu version. The framework, downloaded browser build, operating-system libraries, runtime user, and sandbox policy all influence whether the same script launches consistently. For CI or production jobs:
- Pin or record the Playwright/Puppeteer version and the browser implementation used by the tests.
- Install browsers and system dependencies during image or environment provisioning, not opportunistically during every test run.
- Run checks as the same user and with the same environment that will execute the scheduled workload.
- Keep browser sandboxing enabled where possible, and treat any exception as a security decision tied to the pages being opened.
- When a browser upgrade changes behavior, verify whether the headless implementation or browser channel changed as well.
There is no single apt dependency command established for every Ubuntu release and every Chrome or Chromium build. Use the framework’s current dependency instructions and the browser’s own launch error to avoid installing an unrelated or stale package set.
Best Value
Or skip the browser setup
If your task is to capture website screenshots rather than run browser automation code, ScreenshotNeo offers a screenshot API and MCP server. A single GET request can return a PNG, JPEG, WebP, or PDF. For a quick API call, use cURL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Replace YOUR_API_KEY with your key and change the target URL as needed. See the ScreenshotNeo API documentation for request options. Cookie banners are accepted and removed before capture, along with known newsletter popups and chat widgets; these steps can be turned off. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Sign up for ScreenshotNeo’s free plan.
Frequently asked questions
Can I administer headless Ubuntu without a monitor?
Yes. Once the host is reachable over the network, you can administer it over SSH. A local monitor or desktop session is not required for the browser automation setup described here.
Does Playwright’s headless mode use the same browser as headed mode?
Not necessarily. Playwright’s regular headless Chromium path uses a separate headless shell; selecting the chromium channel opts into its newer Chrome headless implementation. Choose the mode that matches the behavior you need to test.
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 →Does Puppeteer always install Chrome when I install the package?
Usually, the puppeteer package downloads a compatible browser, but package managers may block install scripts. If the browser is absent, use Puppeteer’s browser-install command or allow the install script according to your package manager’s current guidance.

