Installing HHVM 3.2 on a CentOS 6.7 server with Plesk

I wanted to play with HHVM a little bit to see if the speed gain is really as impressive as the benchmarks are showing.

I tried this on a VPS running CentOS 6.7 and Plesk 11.5 and did run into a dependency collision using yum:

Error: Package: psa-libxml-proxy-2.7.8-13032215.x86_64 (@PSA_11_5_30-dist)
           Requires: libboost_program_options.so.5()(64bit)
           Removing: boost-program-options-1.41.0-27.el6.x86_64 (@base)
               libboost_program_options.so.5()(64bit)
           Updated By: boost-program-options-1.54.0-7.el6.x86_64 (hop5)

To get around this I first installed boost:

wget http://www.hop5.in/yum/el6/boost-program-options-1.54.0-7.el6.x86_64.rpm
rpm -ivh boost-program-options-1.54.0-7.el6.x86_64.rpm

After installing boost you can install yum to install the hhvm 3.2 package, like so:

cd /etc/yum.repos.d

sudo wget http://www.hop5.in/yum/el6/hop5.repo

yum clean all

yum install hhvm

To test if hhvm is working:

hhvm --version

This should return something like this:

HipHop VM 3.2.0 (rel)
Compiler: tags/HHVM-3.2.0-0-g01228273b8cf709aacbd3df1c51b1e690ecebac8
Repo schema: c52ba40f4a246d35a88f1dfc1daf959851ced8aa

To use HHVM as a FastCGI handler from Apache/Nginx I first created a simple config file in /etc/hhvm (this directory should have been created installing the hhvm package). I named my config file hhvm.hdf and the content looks like this:

Server {
  Port = 9000
  Type = fastcgi
  FixPathInfo = true
}
Log {
  Level = Verbose
  UseLogFile = true
  Header = true
  File = /var/log/hhvm/error.log
  Access {
    * {
      File = /var/log/hhvm/access.log
      Format = %{X-Forwarded-For}i %l %u %t %v \"%r\" \"%{User-agent}i\" %>s %b %D
    }
  }
}
Eval {
  Jit = true
  EnableHipHopSyntax = true
}

The log level is set to Verbose so in case of trouble we’ll get some more clues. If using HHVM in a production environment you can dial this back.

After setting up the config file you can start HHVM in daemon mode and you won’t have to add all the options using command line switches. Starting it in daemon mode:

hhvm --config /etc/hhvm/hhvm.hdf --mode daemon

Now we’ll have HHVM listening on port 9000. Note that you can also use a UNIX socket instead.
Since we set it to fastcgi mode it will be ready to serve as a FastCGI proxy.

Since my VPS has Plesk 11.5 installed it comes with Apache 2.2 and not 2.4. This is an important detail, because 2.2 does not support mod_proxy_fcgi so we’ll need to use mod_fastcgi’s FastCgiExternalServer directive instead.
If you do have Apache 2.4 then refer to https://github.com/facebook/hhvm/wiki/FastCGI

My VPS was brand new so I didn’t have mod_fastcgi installed yet. To do this:

sudo rpm --import http://dag.wieers.com/rpm/packages/RPM-GPG-KEY.dag.txt
sudo rpm -ivh http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
sudo yum install mod_fastcgi

or install it from source of course.

Next you will have to disable the regular PHP handler in your virtual host config. In Plesk you can simply uncheck PHP support from the website’s settings. This is an important step, because not doing this will have php scripts handled by the regular handler instead of HHVM.

Finally add this to your virtual host config. In Plesk you will find this in /var/www/vhosts/system/hhvm.example.com/conf/vhost.conf
Alternatively you can edit it from the Plesk panel under Websites & Domains -> Webserver Settings in the Additional directives for HTTP field.

Either way add this:

<IfModule mod_fastcgi.c>
    <FilesMatch \.php$>
        SetHandler hhvm-php-extension
    </FilesMatch>

    <FilesMatch \.hh$>
        SetHandler hhvm-hack-extension
    </FilesMatch>

    Alias /hhvm /hhvm
    Action hhvm-php-extension /hhvm virtual
    Action hhvm-hack-extension /hhvm virtual

    FastCgiExternalServer /hhvm -host 127.0.0.1:9000 -pass-header Authorization -idle-timeout 300
</IfModule>

Then restart Apache and you should be all set:

service httpd restart

To test if PHP requests are being handled by HHVM you can create a simple test script calling phpinfo() or
echo defined(‘HHVM_VERSION’)?’Using HHVM’:’Not using HHVM’;

If it’s not working check the HHVM log file first in /var/log/hhvm/error.log

Good luck!

Next up is compiling HHVM myself to get a more up-to-date version. I noticed that in 3.2 Phar::running() isn’t supported yet, which is something that the ZF2 autoloader uses, so with 3.2 I’m unable to run ZF2 applications. This problem should be fixed since HHVM 3.6.