Starting from Ghost Flower, the recent PhantomJS 1.5 release, the standard build for Linux is pure headless without X11. Even Xvfb is not needed. That means you can compile and use PhantomJS in a system without any GUI at all. This would be really useful in some setup such as continuous integration systems, web service platforms, and many others.

How does this work? It’s actually rather easy since Qt supports platform abstraction in the form of QPA, formerly known as Lighthouse. This video should give a good technical overview of the magic of Lighthouse. Leo Franchi from KDAB started the initial work on bringing this Lighthouse awesomeness to PhantomJS some time ago.

The approach I used when finalizing this headless solution was to have Ubuntu 10.04 (Lucid Lynx) virtual machine running without any desktop environment, not even X libraries. Lucid was chosen due to its LTS status and many production systems are still based on it. In addition, if it works there then likely it would work on the newer Ubuntu releases. Here is a screenshot:

After getting PhantomJS built, I ran the rasterizer example to render the famous Tiger head (SVG) to an image (PNG). The image was then uploaded using another example script which demonstrates HTTP POST to send the image to Imagebin. Everything works well in that barebone Lucid server.

Obviously it is not limited to SVG-to-PNG conversion. Normal web page can be captured to an image as well. As predicted, text is still rendered via FreeType and Fontconfig which is nice since we will still get high quality rendering even on an environment sans GUI.

For a quick try, just download the binary package prepared by Jon Leighton (of Ruby on Rails fame). Make sure you pick the right one, 32-bit or 64-bit, depending on your system. Note that there is no need to preinstall Qt or any other libraries as PhantomJS build workflow already takes care of that. You still need FreeType and Fontconfig for the reason mentioned above.

Compiling from source is also quite easy, just follow the documentation:

sudo apt-get install build-essential chrpath git-core libssl-dev libfontconfig1-dev
git clone git://github.com/ariya/phantomjs.git && cd phantomjs
git checkout 1.5

Obviously other Linux distributions can handle that just fine. You may need to tweak the actual packages and package manager but the principle remains the same.

Next: let’s bring PhantomJS to the cloud!

Stay hungry, stay foolish, and stay headless.

  • Anon

    Hi Ariya,

    “How does this work? It’s actually rather easy since Qt supports platform abstraction in the form of QPA, formerly known as Lighthouse”
    So does this allow one to run a Qt app entirely without X11/Xvfb, or just the Webkit portions? If the latter, would it also work on Windows? I’ve been looking for a Windows Xvfb equivalent for automated testing without windows flashing up on screen all over the place 🙂

    • lfranchi

      Yes, it works for any Qt application. Qt 4.8 in lighthouse mode (and any Qt 5 build) contains a built-in platform abstraction layer that lets you choose what platform plugin to use at runtime. Using a plugin that does *not* connect to any X server (such as the modified minimal plugin I originally contributed) provides a X-less build of Qt that is nevertheless as full-fledged Qt. 

      You can run your Qt app against a qpa-enabled 4.8 build w/ the minimal plugin and won’t require Xvfb or X11 or anything else. If your app requires specific things from the windowing system (e.g. fonts) the build-in minimal plugin might not satisfy your needs, though.

      • Anon

        Excellent – thanks for the information, Leo!

  • joe man

    So the program is being run on the server and then scripted to send the picture the website?  Can one run a GUI Qt app drawn in the browser or is this just running Qt code without X and no GUIs run?

    • Can you rephrase your question? I have a hard time understanding it.
      Also, a context of PhantomJS might be needed to understand this blog post, refer to http://code.google.com/p/phantomjs/wiki/QuickStart for a short intro.

      • joe man

         Is there any visual GUI for the Qt apps run on lighthouse-phantomJS?

        • lfranchi

          I do not entirely understand what you are asking: Phantomjs itself *is* a Qt application, using a lighthouse-build of Qt with a modified minimal platform plugin. 

          Any Qt application can run against a Lighthouse-build of Qt without a visual GUI if it is using the Minimal platform plugin.

        • In addition to what lfranchi says:
          PhantomJS is Qt application. It is using QPA (Lighthouse). PhantomJS has a special QPA implementation that does not display anything visually.

  • Mattm

    Are there performance gains w/o the reliance on X11?

    • There is no proof until someone does a statistical analysis of the performance. If there is any difference, it might be quite small compared to the task PhantomJS needs to carry out.
      What is being eliminated by not using X11/Xvfb is the endless protocol overhead going forth and back between PhantomJS (X client) and the X server.

  • Ippa

    Is flashsupport removed with this release? I know they’re planning to remove it soonish.

    • You should check the release notes, it’s right there: “No more support for Flash and other plugins”.

  • brian yang

    has anybody gotten this to work in Ubuntu 12.04 LTS? 

    i was able to install PhantomJS on OSx with HomeBrew and building from source, however, when I try to build from source on Linux Ubuntu it does not install properly. here is the error i’m getting:

    The program ‘phantomjs’ is currently not installed.  You can install it by typing:sudo apt-get install phantomjs

    these are the commands i’m running in the terminal:

    sudo apt-get install build-essential chrpath git-core libssl-dev libfontconfig1-dev
    git clone git://github.com/ariya/phantomjs.git && cd phantomjs
    git checkout 1.5./build.sh

    any help you can offer would be greatly appreciated!

    • Please use the mailing-list for asking questions and/or getting community support.