Upgrading to http2 on apache2.2 on ubuntu 16.04

Webite speed makes a difference. The faster a page loads, the more likely a user is to stick around and buy from you.

Recently I was asked to audit a website and improve it’s performance. Picking off low-hanging fruit improved the website speed considerably – to the point where a regular visitor would instantly notice and appreciate.  But I wanted to look under the hood and see what else could be done.

The very first thing to check should be the underlying host. I’d already established that the host was of decent quality before moving on to make performance improvements to the web application itself. Circling back to take a closer look I discovered that the host was running Ubuntu 16.04 with a version of Apache higher than 2.4.

Checking the http headers with curl I discovered although the website was running TLS, it was using HTTP1.1

HTTP/1.1 200
Date: ...
Server: Apache/2.4.41
Location: ...
Content-Length: 321
Content-Type: text/html; charset=UTF-8

There’s nothing particularly wrong with this. But under many circumstances HTTP2 can increase perceived page speed.

Is HTTP2 A Good Fit For The Webapp?

 

The application was complex, but well-structured. Plus, after I had some familiarity with it due to the performance audit.

HTTP2 can sometimes have no benefit. Or even slow sites down. Smashing Magazine’s introduction to HTTP2 gives an overview of what to look out for and what you might need to change.

I only had to make a couple of changes. To preserve the caching benefits that come with HTTP2 I swapped out a spritesheet for individual images and removed some inline css. The web application was ready. So it was time to configure the server.

Caveat: Don’t Work On A Production Host

Test any significant changes on a host that is not public-facing. Don’t make changes to a host in production. At least not without good reason.  For this particular site I had a staging environment that was a very close mirror of the production website. If something was likely to break, I’d know about it first. And I’d be able to understand the conditions underlying the brokenness before doing anything on the production host.

Getting Ready To Install HTTP2 On Apache On Ubuntu 16.04

Ideally the server would be upgraded to 18.04. This wasn’t possible in this case.  The first thing I did was to check if the http2 module was already installed. I didn’t expect it to be, and it wasn’t.

apachectl -M | grep http

… returned nothing. The module didn’t show up. Good.

Now lets check out the Apache version:

root@bx:/home/mantis# apache2ctl -V | grep -i serv
Server version: Apache/2.4.41
Server built:   2019-08-21T20:43:05
Server MPM:     prefork
Server compiled with....
 -D SERVER_CONFIG_FILE="apache2.conf"

The minimum version required to run HTTP2 module is 2.4. So we are good there.

But we also see that the server is using the preform MPM. This is incompatible with HTTP2. I couldn’t find a good reason not to switch away from prefork. So I changed to the event MPM.

Changing The Apache MPM

a2enmod mpm_prefork
a2enmod mpm_event

This threw an error. The event MPM appears to be incompatible with the php7.2 module.

In this case the php7.2 module wasn’t even being used. The webapp on the server passes all php requests to php-fpm. So the php module could be removed.

a2dissmode php7.2
a2enmod mpm_event
a2dissmode php7.2
a2enmod mpm_event

Then we restart apache:

service apache2 restart

This went smoothly: the website tests were good and there no logged errors or warning. So now to install HTTP2.

Finding And Installing The Apache2 HTTP Module

The http2 module isn’t available in the default repos for 16.04.

The are in Ondrej’s PPA. So we set that up:

add-apt-repository -y ppa:ondrej/apache2
sudo apt-key update
sudo apt-get update
apt-get --only-upgrade install apache2
Caveat

Don’t mix your repos up if you can help it. In this case I had a need to install a trusted repo, and the environment to test things out on. Adding repos that you find catalogued on the net just to solve your short-term problem can create longer term problems for you.

Once the repo installation completed:

a2enmod http2
service apache2 restart

Apache restarted without errors or warnings. The website tests passed.

I checked the http headers:

>> curl -I -X OPTIONS https://[target]
HTTP/2 200 
date: Mon, 1 Aug 2019 09:15:10 GMT
server: Apache/2.4.41 
link: <https://[target]>; <https://[target]>; rel=shortlink
vary: Accept-Encoding
content-type: text/html; charset=UTF-8

Success!

The site is now using HTTP2.

Speed tests showed a small but significant load time for the site as a whole. The most important landing pages had a noticeably faster load time. Most probably due to a design that was economic with images.

Nota Bene

If you are reading this and you want to implement the HTTP2 on Apache, then the Apache howto is mandatory reading. It gives a technical overview, an introduction to the module, and most importantly advice on configuring server push from Apache host configuration files. Installing the module itself is the easy bit. Configuring server push is where things get tricky.