Serving PHP on HTTP/2 with H2O and HHVM (Symfony, WordPress, Drupal...)
This article is not about improvements made in HTTP/2 - as there are plenty of locations for you to read up on the internals. It's a hands on article to get started using HTTP/2 today with popular tools such as Symfony, WordPress and Drupal with the HHVM PHP runtime from Facebook. You can just as well use PHP-FPM.
To get the most out of this article I expect you've got background knowledge on web development and server technologies such as Linux, HTTP, TLS/SSL, networking, etc.. It is not a step-by-step instruction set for dummies, but points out bits and pieces that you can use to get started with HTTP/2 with popular LAMP tools today.
As always with client and server applications, you need to have support for protocols from both sides. HTTP/2 is heavily based on Google's SPDY protocol - prominent in the Chrome browser since 2012 and also supported by Microsoft Edge, Internet Explorer 11, Firefox and others.
This might be a partial reason why this time around the client side support for HTTP/2 is ahead of server implementations. Multiple browsers are ready for HTTP/2 (via TLS) today. So the missing piece of the puzzle currently are mainstream web servers.
PHP on HTTP/2 - State of the server
Focusing on the LAMP platform I'll safely ignore any Node.js and other implementations for now. PHP powers large parts of the web and adoption will make a huge difference on web scale. For a quick look at the popular alternatives I'll take a look at the state of the following for running PHP via HTTP2:
Apache has been around for a long time and is still not a bad option for hosting LAMP applications - especially if kitted with mod_fastcgi. If you're comfortable with building and maintaining your own, then you can start serving HTTP/2 today with mod_h2.
Mod H2 is a module that'll handle communications outside in HTTP/2, leaving everything else intact. Naturally it won't work if you've got a HTTP/1.1 reverse proxy such as Varnish in front of your web server.
In the last five years or so Nginx has become immensely popular. It's a versatile tool for all things HTTP. Reverse proxying, TLS/SSL offloading, or a WebSocket proxy... It's all doable, and the configuration is clearcut. At the moment there is no clean way of serving HTTP/2 from Nginx, but they should support by the end of 2015. I expect Nginx to eat the HTTP/2 market like Apache ate HTTP/1.1. UPDATE: nginx-1.9.5 now contains an experimental HTTP/2 module.
The third option is by far the youngest and definitely the challenger. H2O is a performance oriented web server that natively supports HTTP/2. It's a small project, but seems very promising. As of version 1.3. the server added FastCGI support - finally making it useful for more mainstream web applications and publishing platforms such as Symfony2, WordPress and Drupal.
Caveats (waiting won't kill you)
All of these three options are quite immature (or in the future) and will take a while until HTTP/2 will ship out in CentOS or Debian as the default web server configurations - and first only for Apache and Nginx out of the bunch. H2O is great, but still very much in development.
So in any case you'll probably need to take upgrading to HTTP/2 as a hobby. In most cases it's hard to justify the effort spent for customers in upgrading from 1.1 to 2. While the protocol is essentially a drop-in-replacement, there are bound to be some glitches in deployment itself. Not to mention you'll need to make sure you keep your server software up-to-date manually.
Another drawback is most implementations of HTTP/2 currently only support transfers via HTTPS. So you'll need to purchase a certificate and have the technical skills to install it. If you've the routine it's not really that hard, but still an additional step if you've not been running TLS/SSL before.
It' also worth while that iOS 9 will support HTTP/2. Given Apple's excellent upgrade adoption rate - this'll a very significant factor to go HTTP/2 in 2015.
Having just tested in the new Xcode, I can tell you that iOS supports HTTP/2, not just in Safari but also in apps.
— Cory Benfield (@Lukasaoz) June 10, 2015
Serve PHP via HTTP/2 with H2O and HHVM today
I've been following HTTP/2 and specifically the H2O project from late 2014. In the first stable versions you could run PHP by proxying it to the built-in web server available in PHP since 5.4. This works, but it's meant for development, not production use. From version 1.3 H2O has had support for FastCGI, which allows you to run PHP (and HHVM) in very much the same way as you would with Apache or Nginx.
If you want to do some experimentation with your PHP applications on HTTP/2 here is roughly the setup procedure I went through:
- Install HHVM and verify your PHP application works fine with it. I used the official prebuilt packages.
- Install H2O: https://h2o.examp1e.net/install.html (also, https://calomel.org/h2o.html might help)
- Roll your own or purchase and install an SSL certificate. NameCheap and this Nginx tutorial work great.
- Configure H2O server as you wish. My configuration for PHP rewrite apps:
- Run H2O
- Install some browser that supports HTTP/2 such as the Firefox Developer Edition
- Tail your log and visit your site
If you've got something along the lines of this in your log you're serving HTTP/2:
xx.xx.xx.xx - - [22/Jun/2015:21:12:21 +0200] "GET / HTTP/2" 200 2341 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36 OPR/30.0.1835.59
This setup is not recommended for serious use, but for learning, testing and preparing of HTTP/2 becoming mainstream it's great. If you're reading this on HTTPS, then you're just being... served with Bolt on this setup.
Later I'll look into tools for benchmarking HTTP/2 servers. In the meanwhile I suggest you read up on how to optimize asset delivery for HTTP/2. It's also worth noting that HTTP/2 is independent of CMSes like Drupal.
Special thanks to Kazuho Oku for providing me this shiny toy to play (and learn) with! :)