Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
So, you want to run Chrome headless.

Update May 2017

Eric Bidelman has documented some of the common workflows possible with headless Chrome over in https://developers.google.com/web/updates/2017/04/headless-chrome.

Update

If you're looking at this in 2016 and beyond, I strongly recommend investigating real headless Chrome: https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md

Windows and Mac users might find using Justin Ribeiro's Docker setup useful here while full support for these platforms is being worked out.

You can use chrome --headless on Linux as of M57 but note you'll need to build the binaries yourself for now.

The metabug for adding headless mode to Chromium is over here.

Otherwise, if you're on Ubuntu or working with a Linux VM that isn't working with Linux:

Step 1: Install the Ubuntu dependencies needed:

SSH into your server as a root or do sudo -i.

Then install necessary software:

apt-get update
apt-get install -y xvfb fluxbox x11vnc dbus libasound2 libqt4-dbus libqt4-network libqtcore4 libqtgui4 libxss1 libpython2.7 libqt4-xml libaudio2 libmng1 fontconfig liblcms1 lib32stdc++6 lib32asound2 ia32-libs libc6-i386 lib32gcc1 nano
apt-get install -y python-gobject-2
apt-get install -y curl git

Step 2. Options for starting:

Normal:

xvfb-run --server-args='-screen 0, 1024x768x16' google-chrome -start-maximized > /dev/null &

Start and open a page:

xvfb-run --server-args='-screen 0, 1024x768x16' google-chrome -start-maximized http://www.example.com > /dev/null &

If you're on Windows..

Use Desktops from the MS SysInternals package. You can spawn your Chrome process directly from the "hidden" desktop and keep it working there (I have not personally tested this).

#Other options...

You could try spawning Chrome as a child process using something like Node.js and piping the output back to the terminal. See runChrome.js for an example of how to do this (todo: update to latest Express).

var express = require('express');
var http = require('http');
var cp = require('child_process');
var port = 3000;
var app = express();
//var app = express();
//var server = http.createServer(app);
var chrome_count = 0;
app.get('/', function(req, res){
startChrome(chrome_count++,9222,function chromeStared(err,id,chrome){
res.send('Chrome '+id+' Started\r\n');
console.log('Simulating some data parsing');
setTimeout(function(){
console.log('Shutdown chrome '+id);
chrome.kill('doh!');
},1000);
});
});
app.listen(port);
console.log('Server is listening on port ' + port);
function startChrome(id,port,callback){
var terminal = cp.spawn('bash');
var chrome = {};
terminal.on('exit', function (code) {
console.log('Starting chrome');
chrome = cp.spawn('/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome',[
'--remote-debugging-port='+port,
'--user-data-dir=/Volumes/DATA/repos/scrapper/userdata',
'http://www.chrome.com'
]);
callback(null,id,chrome);
});
setTimeout(function() {
console.log('Sending stdin to terminal');
//terminal.stdin.write('echo "Hello $USER"');
terminal.stdin.write('rm -rf /Volumes/DATA/repos/scrapper/userdata'+'\n');
terminal.stdin.write('mkdir /Volumes/DATA/repos/scrapper/userdata'+'\n');
terminal.stdin.write('touch "/Volumes/DATA/repos/scrapper/userdata/First Run"'+'\n');
terminal.stdin.write('chmod 777 "/Volumes/DATA/repos/scrapper/userdata/First Run"'+'\n');
terminal.stdin.end();
}, 5000);
}
@diasdavid

This comment has been minimized.

Show comment Hide comment
@diasdavid

diasdavid Oct 29, 2014

Hi @addyosmani ! Just found this gist of yours and it was exactly what I was looking for, however, it looks that it is outdated and doesn't work anymore, are you considering revisiting it soon? It would be super helpful. If not, do you know of any other similar resource?

Thank you!

Hi @addyosmani ! Just found this gist of yours and it was exactly what I was looking for, however, it looks that it is outdated and doesn't work anymore, are you considering revisiting it soon? It would be super helpful. If not, do you know of any other similar resource?

Thank you!

@omeraslam-vteams

This comment has been minimized.

Show comment Hide comment
@omeraslam-vteams

omeraslam-vteams Jan 28, 2015

Hi,
while trying to run the following

apt-get install -y xvfb fluxbox x11vnc dbus libasound2 libqt4-dbus libqt4-network libqtcore4 libqtgui4 libxss1 libpython2.7 libqt4-xml libaudio2 libmng1 fontconfig liblcms1 lib32stdc++6 lib32asound2 ia32-libs libc6-i386 lib32gcc1 nano

I receive the following message

Package ia32-libs is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
  lib32z1 lib32ncurses5 lib32bz2-1.0

E: Unable to locate package libmng1
E: Unable to locate package lib32asound2
E: Package 'ia32-libs' has no installation candidate

Hi,
while trying to run the following

apt-get install -y xvfb fluxbox x11vnc dbus libasound2 libqt4-dbus libqt4-network libqtcore4 libqtgui4 libxss1 libpython2.7 libqt4-xml libaudio2 libmng1 fontconfig liblcms1 lib32stdc++6 lib32asound2 ia32-libs libc6-i386 lib32gcc1 nano

I receive the following message

Package ia32-libs is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
  lib32z1 lib32ncurses5 lib32bz2-1.0

E: Unable to locate package libmng1
E: Unable to locate package lib32asound2
E: Package 'ia32-libs' has no installation candidate
@inian

This comment has been minimized.

Show comment Hide comment
@inian

inian May 28, 2015

Does running Chrome in a headless manner theoretically reduce the CPU usage?

inian commented May 28, 2015

Does running Chrome in a headless manner theoretically reduce the CPU usage?

@jond3k

This comment has been minimized.

Show comment Hide comment
@jond3k

jond3k Oct 9, 2015

If you're using Python, why not just use pyvirtualdisplay?

from pyvirtualdisplay import Display
from selenium import webdriver

display = Display(visible=0, size=(800, 600))
display.start()

driver = webdriver.Chrome()

# stuff ...

driver.close()
display.stop()

jond3k commented Oct 9, 2015

If you're using Python, why not just use pyvirtualdisplay?

from pyvirtualdisplay import Display
from selenium import webdriver

display = Display(visible=0, size=(800, 600))
display.start()

driver = webdriver.Chrome()

# stuff ...

driver.close()
display.stop()
@taewookim

This comment has been minimized.

Show comment Hide comment
@taewookim

taewookim Mar 1, 2016

@lame-machine

This comment has been minimized.

Show comment Hide comment
@lame-machine

lame-machine Mar 2, 2016

If you want to use google chrome from the console as google-chrome (for linux), or as a browser for karma, you have to run xvfb: Xvfb :1 -screen 5 1024x768x8 & and export display variable export DISPLAY=:1.5 before

If you want to use google chrome from the console as google-chrome (for linux), or as a browser for karma, you have to run xvfb: Xvfb :1 -screen 5 1024x768x8 & and export display variable export DISPLAY=:1.5 before

@amitaibu

This comment has been minimized.

Show comment Hide comment
@amitaibu

amitaibu Mar 31, 2016

Here's a post about the docker option

Here's a post about the docker option

@mohsen1

This comment has been minimized.

Show comment Hide comment
@mohsen1

mohsen1 May 3, 2016

@addyosmani is nano at the end of packages to install a joke?

mohsen1 commented May 3, 2016

@addyosmani is nano at the end of packages to install a joke?

@krtschmr

This comment has been minimized.

Show comment Hide comment
@krtschmr

krtschmr Jul 11, 2016

@mohsen1 to make sure, people read what they are installing. haha!

@mohsen1 to make sure, people read what they are installing. haha!

@snewcomer

This comment has been minimized.

Show comment Hide comment
@snewcomer

snewcomer Aug 8, 2016

How about for centos? Just find the equivalent pkgs?

snewcomer commented Aug 8, 2016

How about for centos? Just find the equivalent pkgs?

@lmayorga1980

This comment has been minimized.

Show comment Hide comment
@lmayorga1980

lmayorga1980 Sep 12, 2016

@snewcomer I figure out by using these packages but for some reason text is not displayed on the browser.

RUN yum update -y \
  && yum install  \
     ipa-gothic-fonts \
     xorg-x11-fonts-100dpi \
     xorg-x11-fonts-75dpi \
     xorg-x11-utils \
     xorg-x11-fonts-cyrillic \
     xorg-x11-fonts-Type1 \
     xorg-x11-fonts-misc -y

@snewcomer I figure out by using these packages but for some reason text is not displayed on the browser.

RUN yum update -y \
  && yum install  \
     ipa-gothic-fonts \
     xorg-x11-fonts-100dpi \
     xorg-x11-fonts-75dpi \
     xorg-x11-utils \
     xorg-x11-fonts-cyrillic \
     xorg-x11-fonts-Type1 \
     xorg-x11-fonts-misc -y
@Overdrivr

This comment has been minimized.

Show comment Hide comment
@jimthedev

This comment has been minimized.

Show comment Hide comment
@elgalu

This comment has been minimized.

Show comment Hide comment
@elgalu

elgalu Apr 21, 2017

Does someone knows how to browser.manage().window().setSize() when using google-chrome-57 --headless ?

elgalu commented Apr 21, 2017

Does someone knows how to browser.manage().window().setSize() when using google-chrome-57 --headless ?

@elgalu

This comment has been minimized.

Show comment Hide comment
@ripper2hl

This comment has been minimized.

Show comment Hide comment
@ripper2hl

ripper2hl Apr 26, 2017

Very nice works perfectly with Selenium, no window size .
This run on ubuntu 17.04

    @BeforeTest
    public void setupTest() {
        ChromeDriverManager.getInstance().setup();
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--headless", "--disable-gpu");
        driver =  new ChromeDriver( options );
    }

ChromeDriverManager its a project of Boni Garcia
https://github.com/bonigarcia/webdrivermanager

Very nice works perfectly with Selenium, no window size .
This run on ubuntu 17.04

    @BeforeTest
    public void setupTest() {
        ChromeDriverManager.getInstance().setup();
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--headless", "--disable-gpu");
        driver =  new ChromeDriver( options );
    }

ChromeDriverManager its a project of Boni Garcia
https://github.com/bonigarcia/webdrivermanager

@gwuhaolin

This comment has been minimized.

Show comment Hide comment
@gwuhaolin

gwuhaolin Jun 19, 2017

here are some cool project about headless-chrome you gays may like:

  • chrome-render general server render base on chrome.
  • koa-chrome-render chrome-render middleware for koa.
  • koa-seo koa SEO middleware.
  • chrome-pool Headless chrome tabs manage pool, concept come from database connection pool for reuse chrome tab improve performance.

gwuhaolin commented Jun 19, 2017

here are some cool project about headless-chrome you gays may like:

  • chrome-render general server render base on chrome.
  • koa-chrome-render chrome-render middleware for koa.
  • koa-seo koa SEO middleware.
  • chrome-pool Headless chrome tabs manage pool, concept come from database connection pool for reuse chrome tab improve performance.
@angeloassis13

This comment has been minimized.

Show comment Hide comment
@angeloassis13

angeloassis13 Jul 7, 2017

Hi,

I have a java application using cdp to evaluate some javascript code on chrome headless. When I send a large string to be evaluated chrome returns null and the following line is shown on chrome's log: "Too large read data is pending: capacity=1048576, max_buffer_size=1048576, read=1048576"

Is there a way to increase buffer size?

Hi,

I have a java application using cdp to evaluate some javascript code on chrome headless. When I send a large string to be evaluated chrome returns null and the following line is shown on chrome's log: "Too large read data is pending: capacity=1048576, max_buffer_size=1048576, read=1048576"

Is there a way to increase buffer size?

@liang42hao

This comment has been minimized.

Show comment Hide comment
@liang42hao

liang42hao Jul 11, 2017

Virtual display belongs to the past, with almighty chrome doing it all.

Virtual display belongs to the past, with almighty chrome doing it all.

@vpassapera

This comment has been minimized.

Show comment Hide comment
@vpassapera

vpassapera Jul 20, 2017

On Centos 7, with chrome 59, using the --headless flag by itself still causes issues (it straight up doesn't work and you end up having to use real chrome to connect to karma). I still have to use export DISPLAY=99.0 and xvfb-run before running ng test to do headless.

vpassapera commented Jul 20, 2017

On Centos 7, with chrome 59, using the --headless flag by itself still causes issues (it straight up doesn't work and you end up having to use real chrome to connect to karma). I still have to use export DISPLAY=99.0 and xvfb-run before running ng test to do headless.

@positlabs

This comment has been minimized.

Show comment Hide comment
@positlabs

positlabs Aug 15, 2017

Does anyone know if there are plans to make it work without --disable-gpu? I'd like to render webgl content.

Does anyone know if there are plans to make it work without --disable-gpu? I'd like to render webgl content.

@dankonino

This comment has been minimized.

Show comment Hide comment
@dankonino

dankonino Oct 2, 2017

@positlabs yeah, google states that in official docs. For me the biggest problem is the timeout and for me to pass tests timeout needed to be 60k * 5 ms. the same issue I see others having. It actually discourage me to use it now.

@positlabs yeah, google states that in official docs. For me the biggest problem is the timeout and for me to pass tests timeout needed to be 60k * 5 ms. the same issue I see others having. It actually discourage me to use it now.

@joelgriffith

This comment has been minimized.

Show comment Hide comment
@joelgriffith

joelgriffith Nov 10, 2017

Just want to throw it out there that if anyone is looking for a turnkey solution, I've been building https://browserless.io. Aim here is help folks get their stuff off the ground and in production without friction. I'd be more than happy to answer questions or help others' out as it's been something I've worked through about 10 times now.

Just want to throw it out there that if anyone is looking for a turnkey solution, I've been building https://browserless.io. Aim here is help folks get their stuff off the ground and in production without friction. I'd be more than happy to answer questions or help others' out as it's been something I've worked through about 10 times now.

@talamaska

This comment has been minimized.

Show comment Hide comment
@talamaska

talamaska Dec 8, 2017

there is this puppeteer library which can control and spawn headless chrome.

there is this puppeteer library which can control and spawn headless chrome.

@nix86

This comment has been minimized.

Show comment Hide comment
@nix86

nix86 Jan 11, 2018

Is it possible to perform integrated authentication with Chrome headless?

nix86 commented Jan 11, 2018

Is it possible to perform integrated authentication with Chrome headless?

@bearkat2173

This comment has been minimized.

Show comment Hide comment
@bearkat2173

bearkat2173 Jan 27, 2018

Yes, please fix integrated authentication for headless. We are using Selenium with PhantomJS right now, which does support integrated auth, but headless Chrome works so much better otherwise.

Yes, please fix integrated authentication for headless. We are using Selenium with PhantomJS right now, which does support integrated auth, but headless Chrome works so much better otherwise.

@AshCoolman

This comment has been minimized.

Show comment Hide comment
@AshCoolman

AshCoolman Feb 1, 2018

When I run:

apt-get install -y xvfb fluxbox x11vnc dbus libasound2 libqt4-dbus libqt4-network libqtcore4 libqtgui4 libxss1 libpython2.7 libqt4-xml libaudio2 libmng1 fontconfig liblcms1 lib32stdc++6 lib32asound2 ia32-libs libc6-i386 lib32gcc1 nano

I get:

Reading package lists... Done
Building dependency tree
Reading state information... Done
Package ia32-libs is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
  lib32ncurses5 lib32z1

E: Unable to locate package libmng1
E: Unable to locate package liblcms1
E: Unable to locate package lib32asound2
E: Package 'ia32-libs' has no installation candidate

Anyone know what this is about?

Using ubuntu:xenial via docker

Update:

Found these packages here, works for me:

apt-get update && \
    apt-get install -yq gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 \
    libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 \
    libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 \
    libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 \
    ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget

AshCoolman commented Feb 1, 2018

When I run:

apt-get install -y xvfb fluxbox x11vnc dbus libasound2 libqt4-dbus libqt4-network libqtcore4 libqtgui4 libxss1 libpython2.7 libqt4-xml libaudio2 libmng1 fontconfig liblcms1 lib32stdc++6 lib32asound2 ia32-libs libc6-i386 lib32gcc1 nano

I get:

Reading package lists... Done
Building dependency tree
Reading state information... Done
Package ia32-libs is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
  lib32ncurses5 lib32z1

E: Unable to locate package libmng1
E: Unable to locate package liblcms1
E: Unable to locate package lib32asound2
E: Package 'ia32-libs' has no installation candidate

Anyone know what this is about?

Using ubuntu:xenial via docker

Update:

Found these packages here, works for me:

apt-get update && \
    apt-get install -yq gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 \
    libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 \
    libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 \
    libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 \
    ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment