This article aims to walk through the installation process for getting WordPress running on HHVM (HipHop Virtual Machine).

Installing HHVM

For the sake of this case-study, I used Ubuntu “Precise” 12.04 as my linux distribution since I’d be able to install from a simple binary package.  Instructions are currently available for building for Ubuntu 12.04 yourself, or building for CentOS 6.3.  Other distros will probably work with some effort, and you’re encouraged to try.

Unpacking Wordpress

Head to wordpress.org/download to grab the latest tar.gz version of Wordpress and unpack it in a suitable location.  For the purposes of this post, I’ll be using /var/www/wp/

1
2
3
4
 $ cd /var/www
 $ wget 'http://wordpress.org/latest.tar.gz'
 $ tar -zxf latest.tar.gz
 $ mv wordpress wp

 Making a few… tweaks

Update: As of WordPress 3.9, and HHVM 2.0 the following changes aren’t necessary as WP have updated their codebase to play nice with HHVM, and HHVM has updated itself to support more PHP stuff.  Isnt’ Open Source awesome? :)

Wordpress doesn’t quite work “right out of the box” with HHVM because a few of HipHop’s behaviors differ from the PHP it was built for.

First, case-insensitive constants are simply not supported by HipHop.  They’re a bit silly, rarely used, and are more expensive (computationally) than they’re worth.  Fortunately, wordpress only uses this feature in one place (to maintain BC with older plugins), and we can work around it by defining the most common variants.

Open up wp-includes/wp-db.php and look for the line which defines the ‘OBJECT’ constant (line 20 in my version).  We’ll want to take off the third parameter saying to declare it case-insensitively, and add in the lower-case and drop-case versions as alternates. This should be enough to cover 99% of plugins out there.


define('OBJECT', 'OBJECT');
define('Object', 'OBJECT');
define('object', 'OBJECT');

The rest of the changes are actually just temporary work-arounds for fixes which will be in HipHop in the next week or so.  I’ll update this post as those fixes reach github.

As of this writing,_ ini_get(‘post_max_size’)_ will return an empty string, and ini_get(‘upload_max_filesize’) will return a size in megabytes, but without the ‘M’ suffix, so it is interpreted as bytes.  Fixes for both of these are currently pending, so just set them both manually for now.


// wp-admin/includes/template.php in wp_max_upload_size()

#$u_bytes = wp_convert_hr_to_bytes(ini_get('upload_max_filesize'));
#$p_bytes = wp_convert_hr_to_bytes(ini_get('post_max_size'));
$u_bytes =
$p_bytes = 100 << 20; // 100MB, or whatever you'll be setting

Update: Both post_max_size and upload_max_filesize have been updated to return sane values and these changes are no longer required.

magic_quotes_runtime is (happily) not supported by HipHop.  get_magic_quotes_runtime() probably should have just quietly returned false, but for whatever reason it was implemented as throwing a “not implemented” exception.  A fix for this is currently pending, so hard-code a zero (false) for now.


// wp-admin/includes/class-pclzip.php in privDisableMagicQuotes()
#$this->magic_quotes_status = @get_magic_quotes_runtime();
$this->magic_quotes_status = 0;

// wp-includes/class-phpmailer.php in EncodeFile()
#$magic_quotes = get_magic_quotes_runtime();
$magic_quotes = 0;

Update: get_magic_quotes_runtime() has been updated to always return 0 (false) rather than throwing an exception.  This tweak no longer needs to be made.

Create a config file

The syntax for HipHop’s web server is pretty extensive, but the following placed in /etc/hhvm.hdf should be enough to get you going.  Refer to options.compiled for other settings.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// /etc/hhvm.hdf

Server {
  Port = 80
  SourceRoot = /var/www/
}

Eval {
  Jit = true
}
Log {
  Level = Error
  UseLogFile = true
  File = /var/log/hhvm/error.log
  Access {
    * {
      File = /var/log/hhvm/access.log
      Format = %h %l %u %t "%r" %>s %b
    }
  }
}

VirtualHost {
  * {
    Pattern = .*
    RewriteRules {
      dirindex {
        pattern = ^/(.*)/$
        to = $1/index.php
        qsa = true
      }
    }
  }
}

StaticFile {
  FilesMatch {
    * {
      pattern = .*.(dll|exe)
      headers {
        * = Content-Disposition: attachment
      }
    }
  }
  Extensions {
    css = text/css
    gif = image/gif
    html = text/html
    jpe = image/jpeg
    jpeg = image/jpeg
    jpg = image/jpeg
    png = image/png
    tif = image/tiff
    tiff = image/tiff
    txt = text/plain
  }
}

You may wish to add other directives and static file extensions, but this will get you started.  The RewriteRule is to accomodate the fact that HipHop does not (currently) support a DirectoryIndex style directive.  While this feature is currently in development, we can get by with a general case rewrite rule.

Start the webserver

Pretty straight-forward, just press go:

1
sudo /usr/bin/hhvm --mode daemon --user web --config /etc/hhvm.hdf

Assuming of course you have a user designated for your web server to run as named ‘web’.  Rename this one as needed.

Wordpress setup

From here, setup follows the normal “Famous 5 Minute Installation”.  If you run into any trouble, check that you updated system files as described above, look into your error.log, or leave a comment here or on our Facebook Page.

Comments


  • Sandeep: Nice blog and well documented.
  • Vadim Sigaev: Very nice post, but please tell, where i can find documentation on HHVM for future reading? First of all, is it somewhere specification about hhvm.hdf structure? And also it's very interesting to read about debugging features.
  • sgolemon: At the moment, all the real documentation is in git under the doc/ directory, but it's a bit dry and hard to read casually. I plan to publish a version of the PHP manual with HipHop details merged in where appropriate (particularly under configuration and runtime variances). https://github.com/facebook/hiphop-php/tree/master/doc
  • heinhtetaung: i did everything you say .. after that src/hhvm/hhvm --mode daemon --user web --config /etc/hhvm.hdf nothing happend. i try other src/hhvm/hhvm test.php --mode s --port 8080 mapping self...n mapping self took 0'00" (36559 us) wall timen loading static content...n searching all files under source root... analyzing 9526 files under source root... loaded 0 bytes of static content in total loading static content took 0'00" (75376 us) wall timen could not allocate 1210089471 bytes for translation cache what's wrong ?
  • sgolemon: In the case of the first attempt, can you define: "Nothing happened"? Nothing should appear to happen on the command line since you're starting up the server and it's sitting around waiting for web requests. Does `ps ax` show it running? Do you get anything when trying to browse to that server with your webbrowser? On the second one, you're mixing verbs. You've selected `--mode server` which is going to make HHVM try to load up a whole directory full of files (though you haven't specified which directory). What you have done is a pass a single file name with is more appropriate to just running as a command-line script (without passing the --mode server flag).
  • heinhtetaung: thank you for your reply , i already check `ps ux ` . i dont see that process and any listen port 80 . i try mode server , src/hhvm/hhvm --mode s --user web --config /etc/hhvm.hdf could not allocate 1210089471 bytes for translation cache
  • rynop: First off thanks for all the hard work. Do you have a list of the php extensions you support? I'm wondering if things like APC, cURL, memcache, pdo MySQL etc are supported. I found https://github.com/facebook/hiphop-php/wiki/Extensions-and-modules-roadmap but its a bit outdated (last mod 2yrs ago).
  • Steve McNally: Thanks for sharing this with the community. I'm reading the more general hhvm update info, too. Q: the hhvm is concerned "exclusively" with php execution time? are there db-layer improvements, too?
  • Lewis Cowles: Are there many benefits to using Wordpress under HHPHP? Any stats? Also what about other libraries like Codeigniter. Lastly what version of PHP is HHPHP compatible with?
  • Nick_vh: Well, I tried to get it running with Drupal, but somehow it seems to be lacking a lot of verbose output to help you understand where it goes wrong I documented the whole process below and used vagrant to made sure that my machine was not corrupt. http://nickveenhof.be/blog/getting-drupal-7-almost-running-hhvm The server started in daemon mode, and then shows a message "Not Found". It also does not report anything in the error.log (while it does have write access) I'd appreciate if there were more runtime debug modes? Perhaps it could be ran in --mode server and show the errors in the terminal? Perhaps I'm not seeing the obvious?
  • Nick_vh: Ok, I played with it even more and it seems that it might be that HHVM does not support some php extensions yet such as PDO? Is that right? After figuring out how to debug it, I posted the stacktrace in my blog mentioned above For others : sudo hhvm --config /etc/hhvm.hdf --user YOUR_WEB_USER --mode daemon -v "Log.Level=Verbose" -v "Log.NoSilencer=on" -v "Log.Header=on" tail -f /var/log/hhvm/error.log Don't forget to kill to process if you want to try it again.
  • rynop: Here they are: https://github.com/facebook/hiphop-php/tree/master/src/runtime/ext I'm trying to start via: ryan: sudo /usr/bin/hhvm --mode daemon --user "www-data" --config /etc/hhvm.hdf But I keep getting the following errors: cat error.log Failed to initialize central HHBC repository at '/home/ryan/.hhvm.hhbc' Failed to initialize central HHBC repository at '/var/www/.hhvm.hhbc' Got any pointers on where I can read about how to configure where this .hhvm.hhbc goes? its not in index.php?file=options.compiled . Also why is it trying to write anything to the user im logged in as dir? i specified --user "www-data" and am launching cmd via sudo...
  • Rod Salazar: It's pretty clear what is wrong, there is not enough memory for the translation cache, as specified by that error! 'could not allocate 1210089471 bytes for translation cache' The hhvm daemon is also spitting out that error except you can't see it because it is a daemon process.
  • rynop: http://www.hiphop-php.com/wp/?p=257 explains all about hhbc. Sorry for all the posts. Hopefully this saves the next person time in connecting the dots.
  • sgolemon: Yeah, sounds like you got it figured out. Sorry for the delay getting back to you.
  • sgolemon: Correct. HipHop is just about speeding up the PHP execution time portion of the stack. db-layer speed-ups (which is the first thing anyone should address) are out of scope, but I'm sure you'll find many posts on technique involving memcached, judicious use of indexes, etc... for that.
  • sgolemon: Our (unpublished) stats say that facebook.com would require aproximately 6x as many front-end machines if we were using stock PHP. ((Note that the FB codebase is tightly tuned to HipHop)) I've also got some numbers showing hiphop/repojit performing at about 4:1 for more generic codebases like Wordpress. Beyond speed, there's the differences in what we're doing with the language syntax itself. HipHop had generators long before PHP (php.net just added these for 5.5), and we've got a strict typing implementation on its way down the pipe which should improve development a bit.
  • sgolemon: As replied on your blog (and twitter), I didn't see the same issues as you, primarily because I ran into other problems at an earlier stage with the lack of support for custom stream wrappers. Short version: Yes, drupal and hiphop aren't friends at this point. We'll have to do some work there.
  • rynop: Np. Prob not the right place to ask this question is - but wondering if you could touch on the following topics in future blog posts 1) how does FB store session data across nodes? You back your sessions with memcache? 2) Also wondering how you roll out code updates and "warm" up the cache/clear old cache without disrupting incoming requests. With apc+fpm I just clear the opcode and requests in flight are not impacted, while new requests get the code updates. I'm still not clear on how this works in the wild with HHVM+JIT. Do you just run '/usr/bin/hhvm-analyze' , copy the /tmp/hphp_XXXXX/hhvm.hhbc.sq3 to 'Repo { Central { Path' and kill/start the /usr/bin/hhvm?
  • sgolemon: Yeah, this isn't the spot to going into it, besides I'm sure it's already been covered on the Facebook Engineering Blog: https://www.facebook.com/Engineering?sk=notes If you still have trouble finding it, I'll ask around for some more specific links.
  • Victor: Is there any way to create a friendly url's system using HHVM? I've changed the RewriteRule but I could only call the GET of the page, with no success in calling css and js's files and folders. Is there any solution to the directives “RewriteCond %{SCRIPT_FILENAME} !-f” and “RewriteCond %{SCRIPT_FILENAME} !-d” on HHVM?
  • Eric: I'm using Ubuntu 12.10 and compiled HHVM using the guide at the wiki. I tend to use the laravel framework for my webpages; however, functons such as function_exists()/class_exists() isn't supported. I saw that they were supported using the --hphp -v "AllVolatile=true" option. But that requires me to use "old" hphp, right? Which isn't going to be supported after mid 2013? Is there by any chanse, possible, to use those functions, using HHVM?
  • Alex Babira: I used the pre built binary to get hip hop from here https://github.com/facebook/hiphop-php/wiki/Prebuilt-packages-on-ubuntu-12.04 of course i run it on ubuntu 12.04 lts. The problem is hhvm is not starting sudo /usr/bin/hhvm --mode daemon --user "my user" --config /etc/hhvm.hdf does nothing..... "netstat -tulpn" does not display anything waiting on port 80 or whatever port I assign to HHVM via the conf file, "ps aux" does not display any processes related to hhvm, the wierd thing is that when i try to run hhvm in verbose mode i get some messages in my error.log but they dont seem to be errors here are the lines that get printed [Sat Apr 13 23:01:06 2013] [hphp] [2526:7f7369430e40:0:000001] [] mapping self... [Sat Apr 13 23:01:06 2013] [hphp] [2526:7f7369430e40:0:000002] [] mapping self took 0'00" (55495 us) wall time [Sat Apr 13 23:01:06 2013] [hphp] [2526:7f7369430e40:0:000003] [] loading static content... [Sat Apr 13 23:01:06 2013] [hphp] [2526:7f7369430e40:0:000004] [] searching all files under source root... [Sat Apr 13 23:01:06 2013] [hphp] [2526:7f7369430e40:0:000005] [] analyzing 1 files under source root... [Sat Apr 13 23:01:06 2013] [hphp] [2526:7f7369430e40:0:000006] [] loaded 0 bytes of static content in total [Sat Apr 13 23:01:06 2013] [hphp] [2526:7f7369430e40:0:000007] [] loading static content took 0'00" (2442 us) wall time I am guessing that's because of the log level,(Note that the root in this case is just a simple index.php file containing an echo statement, not wordpress).
  • Adrian: Pardon my ignorance on this but I have a pretty basic question. Does running an application on hiphop require Apache (or other web server) and php installed or hiphop provides that functionality. So Install Apache, install php, install mysql - then install hiphop?
  • sgolemon: Well, HipHop *is* an implementation of PHP, so no: You don't need PHP installed. It's also got it's own web server built in. Notice how the "Configuring" section talks about port numbers and virtual hosts and logging? So no to that as well. You *can* put Apache in front of HipHop if you need access to some of the additional feature Apache has, but in that case Apache would just be proxying to HipHop's web server.
  • sgolemon: Where did you get the idea they weren't supported?
  • Adrian: I compile and installed word press the other day. It was much certainly quicker. I am assuming that under load it would continue to outperform standard php and apache installs. It will be interesting to watch it mature over the next few years.
  • Adrian: that link is broken
  • George Jempty: options.compiled link is broken, it's now here: https://github.com/facebook/hiphop-php/blob/master/hphp/doc/options.compiled
  • Denis: Please make bench comparing to APC.
  • Dylan R Madisetti: So I got Wordpress running on HipHop. Woop woop! I admit, I cheated and used the binaries, but it was a fairly painless process on Ubuntu 13.2 (I built from scratch on Debian squeeze the other day and it was killer.) In addition to the post you have here, I had to add DefaultDocument = index.php to the server block and JitASize = 67108864 JitAStubsSize = 67108864 JitGlobalDataSize = 16777216 to the eval block (My poor VM couldn't take it otherwise) just playing around with this it seems wordpress defined rewrite rules don't work. Considering trying to run hhvm with nginx as detailed here https://github.com/facebook/hiphop-php/wiki/Using-nginx-as-Front-Server-to-HipHop to see if I can get something to give. or is there a way to do this solely with hiphop?
  • Joe Wang: Dear Sara, Thank you for the great guide! Got a problem though, its not working for me... I just created a new AWS EC2 Ubuntu 12.04 LTS instance and installed a prebuilt package of Hiphop VM (v2.0.2). I applied the Object declaration fix and forgo the other Wordpress tweaks as they appear to be striked out. However Wordpress (brand new 3.4.2 installtion) still won't run. I can visit separate pages via MY_DOMAIN/wordpress/php-page.php (must have the .php suffix, otherwise chrome will just display "Not found"), but Wordpress as a whole just doesn't run. The error that I see are either "web page not available" or simply "not found". I tried to run the server with and w/out the config or user settings to the same results.
  • Dylan R Madisetti: Wordpress works by hitting [WordpressDirectory]/index.php which the loads everything else. Depending on the referring url, Wordpress will spit up various pages. If you default hiphop in the server block of the configuration with DefaultDocument = index.php then you should be good to run. You will not be able to use permalinks, but leaving posts in their ?p=number form should let you spit up pages/posts. I have not found much documentation on making this working with fully formed slugs, but I'm looking into it. Ideally I want to be running a multisite wordpress from hiphop.
  • David Michael: Joe, I am getting the same issue you are. I was able to install correctly but when trying to go to site/index.php i get a not found error.
  • Zijin Zhang: I followed this tutorial.When I requested /wp-admin everything worked perfectly.However,when I requested /,I was simply notified 'not found'.So I looked into error log,nothing wrong.Then I looked into access log,I fount that when I requested /,hhvm responded 301 or 302. Can someone shed some light on this?
  • Frank: I tried to get around this problem with an nginx front end but could not get it to work using proxy_pass, despite it working fine for php5-fpm using fcgi_pass. Very frustrating. I'd switch to hphp and ditch php5-fpm+xcache+opcache tomorrow for Wordpress if it could do clean URLs.
  • Al: Don't forget about owner of "SourceRoot = /var/www/: chown web /var/www -R
  • Clotilde Roes: This is really great and awesome.
  • xyz: Hi, I am a new bee, i tried to configure hhvm with the above steps and finally succedded to execute simple hello world through command prompt, but fail to execute the same *.php file through URL by using the above "/etc/hhvm.hdf " config file. Can anybody help me. I already wasted my 4days with boost version....:( Thanks in Advance
  • Vasken Hauri: As of r27377 of WordPress, the lower-case constant issue has been fixed for the purpose of hhvm compatibility (thanks to Andrew Nacin). https://core.trac.wordpress.org/changeset/27377
  • Joel Marcey: Yay! :)
  • Philip John: As of last night there is a HHVM config available for Varying Vagrant Vagrants (VVV): https://github.com/johnjamesjacoby/hhvvvm
  • MRoeling: Updated list: https://github.com/facebook/hhvm/tree/master/hphp/runtime/ext
  • James: Sorry for raising this posts from death but I can't find the aforementioned post. Most specifically "how does FB store session data across nodes". We are looking into deploying hhvm in a load balanced scenario.
  • Cesar Falcao: I got it working fine Nginx+MariaDB10 and Wordpress, but the performance is dead slow. I got 1500 concurrent users, but now I can't get more than 50 and its all very long response times, timeout and errors. I got JIT on, I can't find any info about what to do.
  • Cesar Falcao: EDIT: 1500 concurrent users with PHP 5 in the same VPS, 123 ms avg response.
  • Blake: Just an FYI: HHVM no longer supports the built-in webserver as of 3.0.0. Please use your own webserver (nginx or apache) talking to HHVM over fastcgi. https://github.com/facebook/hhvm/wiki/FastCGI