Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
npx 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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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 install command. For Puppeteer, run npx puppeteer browsers install and 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.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.