My latest LAMP project, is to put together a stack that comprises Apache 2.4.18, with HTTP/2 support and Google PageSpeed, running on top of Ubuntu 16.04. Ubuntu 16.04 isn’t due to be released until next month, so it isn’t yet available as an installable image on most cloud compute services. I hope this simple tutorial will be useful to others like me.
I’m basically indifferent, at this time, to Apache or Nginx, just so long as my performance and maintenance goals are met. My key requirements are for a fast server that supports HTTP/2 and can run Google’s PageSpeed. I didn’t find a great difference between Apache and Nginx (see earlier post).
The maintenance bit is more problematic. I am quite capable of compiling and patching stuff myself. However, I do also want a solution that requires very minimum maintenance in the long-term. I don’t have time to babysit my server.
After much consideration, I’ve decided to go with Apache. HTTP/2 is supported from Apache 2.4.17. However, neither CentOS (and RHEL) nor Ubuntu currently includes a new enough Apache. But, the upcoming Ubuntu 16.04 LTS will include Apache 2.4.18! However, since Ubuntu 16.04 isn’t due to be released until next month, no cloud compute service currently offers it as an installable image.
All’s not lost. I can always start with an older Ubuntu 15.10 image, then upgrade it to pre-16.04. It turns out there’s also a small problem. Ubuntu decided not to include HTTP/2 support in its build of Apache 2.4.18. So, well, I’ve got to fix something up there. I’ll touch on this bit again later.
Install Ubuntu pre-16.04
Let’s get on with the tutorial. I’m assuming we will start off with a virtual machine that has Ubuntu 15.10 installed. We can upgrade to pre-16.04 quite easily. I’m doing it from command-line, my preferred mode of working, of course.
First, just make sure the server is up-to-date.
$ apt-get update $ apt-get upgrade
Next, we’ll do the actual upgrade to 16.04. It’s the development branch, of course, since 16.04 is not yet released at this time. It’s better that you do the following through the VM console. Your cloud service should have some sort of console interface. You can also try through SSH, although it could be risky if your SSH connection breaks. Make sure you have a root account password to login with, since some services (e.g. OpenStack) do not use passwords by default.
$ do-release-upgrade -d
There’s going to be quite a bit going on, including some interactive prompts that you have to step through during the release upgrade. At the end Ubuntu will reboot.
Check that your Ubuntu has indeed been upgraded.
$ cat /etc/os-release
Next, just quickly check that your packages are all up-to-date.
$ apt-get update $ apt-get upgrade
That’s it, you now have Ubuntu 16.04, or at this time just its development branch.
Install Apache with HTTP/2
Here’s my plan. Ubuntu currently disables building of HTTP/2 support, because the feature is experimental. I thought they could have just disabled runtime configuration, which would then allow more adventurous people to turn it back on easily. Perhaps they would change their mind in future, but at this time, it means we’ve got to rebuild Apache ourselves.
Some of the commands in this section doesn’t require root. So I’ll assume we’ll not login as root, and will sudo whenever necessary if root was required.
Start by getting the development tools. I dislike having development tools on a live production server. In practice, I suppose you could find another Ubuntu VM to do this work.
$ sudo apt-get install devscripts build-essential fakeroot
Get Apache and libnghttp2. The latter is required for building Apache with HTTP/2 support.
$ sudo apt-get install apache2 $ sudo apt-get install libnghttp2-dev
We can now get on with recompiling Apache with its Ubuntu source package.
$ mkdir apache2 $ cd apache2 $ apt-get source apache2 $ sudo apt-get build-dep apache2 $ cd apache-2.4.18 $ fakeroot debian/rules binary
Notice that we didn’t actually have to edit anything. Apache will build with HTTP/2 support automatically when libnghttp2-dev is installed.
Now, there’re two ways forward. You can install the resulting apache2-bin package. But I much rather continue to use the original Apache package from Ubuntu in place. Instead, I’ll just copy the mod_http2.so file from the new Apache build into the live system. This way, Apache continues to get updated through Ubuntu’s packaging system.
$ sudo cp debian/apache2-bin/usr/lib/apache2/modules/mod_http2.so /usr/lib/apache2/modules/
If you much prefer to install the new package itself:
$ sudo dpkg -i ../apache2-bin_2.4.18-1ubuntu1_amd64.deb
Do whichever works better for you.
You’ll still have to load the HTTP/2 module. Create the file
/etc/apache2/mods-available/http2.load and put this inside:
LoadModule userdir_module /usr/lib/apache2/modules/mod_userdir.so
$ a2enmod http2 $ service apache2 restart
That’s it. Note that some configuration is required to actually get HTTP/2 enabled. That’s beyond the scope of this tutorial.
PageSpeed and Others
Google PageSpeed is easy to install. Just following the instructions from the PageSpeed Install from Packages page. You do need to configure PageSpeed too.
Ubuntu 16.04 includes HHVM in its package repository, a nice thing to have if you run PHP apps, like WordPress. Setting it up is also beyond the scope of this tutorial, but I thought I should at least mention, because it’s one of the reasons I’ve decided to go with Ubuntu 16.04, even though I’ve thus far been more of a CentOS user.
This installation plan lets you leave Ubuntu to keep your system updated, just except for the mod_http2.so that had been manually copied into place, if you had followed my recommendation. This is sufficiently convenient, at least for me, to keep abreast of all the security fixes. There’s only the mod_http2.so bit that I’ve got to watch out for, manually. In fact, in an emergency, like if there were an critical vulnerability with mod_http2.so or its dependencies, and I’ve no time or it’s not convenient to compile a fix, it’s quite easy to simply disable HTTP/2 as an interim solution.
$ a2dismod http2 $ service apache2 restart
Just that two commands and HTTP/2 support is removed. (This also depends on the Apache configuration being setup properly with
IfModule mod_http2.c blocks.)
This is simple enough to be easily maintainable in my books.