Headless Chrome on Heroku

I’ve been experimenting with headless chrome for a Link Unshortener tool I’ve built to take screenshots of websites. I’ve been using BrowserShot which is great. It’s a php wrapper around Puppeteer which makes it simple to use in Laravel. To experiment more with Puppeteer, I wanted to get a node app running on Heroku. Overall it’s pretty straight forward but there are a few gotchas.

Here is a sample project that should get you started. Clone this and take a look at the source. You’ll notice I specified the node.js version in the package.json file. This is required for Heroku to know what version of node to use. Another issue I ran into is to run Puppeteer on Heroku you have to specify –no-sandbox. They last hurdle was adding the puppeteer Heroku buildpack. Follow the steps below and you should have a working screenshot app running locally and on Heroku. These instructions assume you are familiar with node and Heroku.

Setup Steps

  1. Clone sample project: git [email protected]:timleland/headless-chrome.git
  2. Make sure you are in the correct directory: cd headless-chrome
  3. Install node dependencies: npm install
  4. Run the app to test: npm start
  5. Open your browser to: http://localhost:8080/?url=google.com
  6. You should have download a png screenshot of google.com
  7. To deploy to Heroku make sure you have the Heroku cli tool installed 
  8. Create a new app on Heroku: heroku create APPNAMEHERE
  9. Add the puppeteer heroku buildpack: heroku buildpacks:add https://github.com/jontewks/puppeteer-heroku-buildpack
  10. Deploy to Heroku: git push heroku master
  11. Now just append the query string url=site.
  12. You should now have a working Heroku app that will screenshot any url you send it.

Leave your questions and feedback in the comments below.


Also published on Medium.

21 thoughts to “Headless Chrome on Heroku”

      1. @Tim

        Yeah, sorry I meant: `heroku buildpacks:add heroku/nodejs` (Note the `add` instead of `set` as `set` seems to overwrite the existing buildpacks)


  1. Hello!

    Thanks for the tutorial in the first place. I’ve followed the steps but I got the following error in my console:

    /app/node_modules/puppeteer/.local-chromium/linux-508693/chrome-linux/chrome: error while loading shared libraries: libcairo-gobject.so.2: cannot open shared object file: No such file or directory

    Do you know anything about this issue?

      1. I’ve already done that and it’s still not working. I’ve added the libcairo-gobject to the buildpack and I’ve managed to get it run.

  2. Thank you,.
    2018-01-08T21:50:44.412485+00:00 heroku[router]: at=error code=H14 desc=”No web processes running” method=GET path=”/?url=google.com” host=infinite-headland-44709.herokuapp.com request_id=85fa1725-7ee0-4404-bb19-8dd54fbfffbe fwd=”″ dyno= connect= service= status=503 bytes= protocol=https
    2018-01-08T21:50:44.862414+00:00 heroku[router]: at=error code=H14 desc=”No web processes running” method=GET path=”/favicon.ico” host=infinite-headland-44709.herokuapp.com request_id=46644015-4aed-4038-a941-80321c466eb0 fwd=”″ dyno= connect= service= status=503 bytes= protocol=https

    #2 Tried doing this
    heroku ps:scale web=1


    Scaling dynos… !
    ▸ Couldn’t find that process type.

    #4 Tried removing buildpacks
    heroku buildpacks:remove heroku/nodejs
    heroku buildpacks:remove https://github.com/jontewks/puppeteer-heroku-buildpack

    #5 Tried doing this now
    heroku ps:scale web=1


    Scaling dynos… !
    ▸ Couldn’t find that process type.

    Not sure if any issues with https://github.com/timleland/headless-chrome.git

  3. After following your instructions I’m getting this weird error when launching puppeteer:

    TypeError: input.on is not a function
    2018-01-19T06:16:08.710918+00:00 app[web.1]: at new Interface (readline.js:181:11)
    2018-01-19T06:16:08.710919+00:00 app[web.1]: at Object.createInterface (readline.js:64:10)
    2018-01-19T06:16:08.710922+00:00 app[web.1]: at waitForWSEndpoint (/app/node_modules/puppeteer/lib/Launcher.js:195:10)
    2018-01-19T06:16:08.710921+00:00 app[web.1]: at new Promise ()
    2018-01-19T06:16:08.710923+00:00 app[web.1]: at Function.launch (/app/node_modules/puppeteer/lib/Launcher.js:133:39)
    2018-01-19T06:16:08.710924+00:00 app[web.1]: at
    2018-01-19T06:16:08.805193+00:00 app[web.1]: events.js:183
    2018-01-19T06:16:08.805197+00:00 app[web.1]: throw er; // Unhandled ‘error’ event
    2018-01-19T06:16:08.710920+00:00 app[web.1]: at Promise (/app/node_modules/puppeteer/lib/Launcher.js:196:25)

    Any idea what’s going on? Your help is much appreciated :).

  4. Has anyone tried to start puppeteer with –proxy-server option on Heroku? I’m getting always timeout when attempting to connect (not a problem of the proxy, it works on my local env)


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.