Apache HTTP/2 Web Server Setup on Ubuntu 14.04

Today, I'm going to install the latest Apache2 and PHP5 on an Ubuntu server and enable HTTP/2. This guide doesn't cover the fact that HTTP/2 only works over HTTPS, so you would ultimately need a SSL certificate to get the benefits of HTTP/2.

There is an alternative to re-configuring your server(s) and paying for a SSL certificate - use CloudFlare, which includes SSL certs, HTTP/2 support, caching, and DDoS protection, all for free. Personally, I like the features of the Business plan and use it for some projects but this website is running on the free plan.


Upgrade

To upgrade an existing Apache system to use HTTP/2, follow these simple instructions:

$ sudo -i
$ apt-get install python-software-properties
$ add-apt-repository -y ppa:ondrej/apache2
$ apt-key update
$ apt-get update

The above commands add the latest apache2 repository to your system and updates the list of available packages your system is aware of.

$ apt-get --only-upgrade install apache2 -y

Enable the http2 apache mod.

$ a2enmod http2

Edit your Apache2 virtual host configuration to include the Protocols directive.

<VirtualHost *:443>
 # for enabling h2 on an https server
 Protocols h2 http/1.1

 # other SSL configurations go here
 # ...
</VirtualHost>

Restart Apache2.

$ service apache2 restart

Install

If you aren't upgrading, and need to install Apache and PHP from scratch, SSH into your freshly created Ubuntu 14.04 system and follow these instructions:

  1. Update and upgrade the existing packages/software, then reboot, just in case it's required.
    You probably don't want to upgrade everything and reboot a system used for a production website. Test these commands first on a clone/backup of your system and then proceed slowly, making sure to keep track of the commands you run so you can replicate your results. Virtual machines from Amazon EC2, Google Compute Engine or Microsoft Azure make cloning instances real easy.

    $ sudo -i
    $ apt-get update && apt-get upgrade -y && apt-get dist-upgrade -y
    $ reboot    
    
  2. Reconnect via SSH and install the latest Apache2/PHP5 packages.

    $ sudo -i
    $ apt-get install python-software-properties
    $ add-apt-repository -y ppa:ondrej/apache2
    $ add-apt-repository -y ppa:ondrej/php5
    $ apt-key update
    $ apt-get update && apt-get upgrade -y
    $ apt-get install -y php5-fpm apache2
    

    At this point, Apache2 and PHP5-FPM should have started and if you were to visit your public IP, you would see "Apache2 Debian Default Page".

  3. Enable Apache2 mods, including http2.

    $ a2enmod proxy_fcgi proxy proxy_http http2 ssl expires headers rewrite
    
  4. Change php5-fpm config to use TCP connection instead of socket using one command.

    $ sudo sed -i "s/listen =.*/listen = 127.0.0.1:9000/" /etc/php5/fpm/pool.d/www.conf
    

    Or change php5-fpm config to use TCP connection instead of socket manually using editor.

    $ sudo nano /etc/php5/fpm/pool.d/www.conf
    

    Find this line: "listen = /var/run/php5-fpm.sock", replace it with this: "listen = 127.0.0.1:9000". Save and exit: CTRL-X, Y, Enter

  5. Open and edit the default HTTP virtual host.

    $ nano /etc/apache2/sites-enabled/000-default.conf
    
  6. Add these lines to the default HTTP virtual host config file, this assumes you have your DocumentRoot set to /var/www/html, in an existing setup this could be different and would need to be modified.

    <VirtualHost *:443>
     ServerAdmin [email protected]
     DocumentRoot /var/www/html
     ServerName example.com
    
    
     ErrorLog ${APACHE_LOG_DIR}/error.log
     CustomLog ${APACHE_LOG_DIR}/access.log combined
    
    
     # php handler
     # don't use php? you can comment out this line then
     ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/$1
    
    
     # for enabling h2 on an https server
     Protocols h2 http/1.1
    
    
     # other SSL configurations go here
     # ...
    </VirtualHost>
    

    Note: If you change your DocumentRoot, you will also need to change ProxyPassMatch.

  7. Restart services for changes to Apache 2.4.18 and PHP 5.5.34 to take effect.

    $ service apache2 restart
    $ service php5-fpm restart
    

    The webserver is now setup and configured to use proxy_fcgi and php-fpm. Make sure to check /var/log/apache2/error.log for any PHP errors.

  8. (optional) Install and configure PageSpeed Module.

    $ cd /tmp
    $ wget https://dl-ssl.google.com/dl/linux/direct/mod-pagespeed-stable_current_amd64.deb
    $ dpkg -i mod-pagespeed-*.deb
    $ nano /etc/apache2/mods-enabled/pagespeed.conf
    $ service apache2 restart
    
  9. (optional) Install other PHP extensions and software packages.

    # redis
    $ apt-get install -y redis-server php5-redis
    
    
    # memcached
    $ apt-get install -y php5-memcached memcached
    
    
    # restart php
    $ service php5-fpm restart
    
  10. Grab a beverage and celebrate your new fast HTTP/2 web server!

    $ exit
    

All that is left is to make a few custom modifications to your virtual host config file to enable TLS (add your SSL certificate) and you'll be all set! Mozilla's SSL Configuration Generator could help you setup your HTTPS server if you are unsure how to proceed.

What's left to do?
  1. Modify the virtual host to include a domain and TLS (SSL certificate)
  2. Test your domain for HTTP/2 using Chrome
Related Resources
Server Push

Apache 2.4.18 has been released with support for Server Push. To use HTTP2's server push features with Apache, you must add a Link header to your response. When a Link has the rel=preload attribute, it will be pushed as long as the browser supports it.

<Location /index.html>
    Header add Link "</css/site.css>;rel=preload"
    Header add Link "</images/logo.jpg>;rel=preload"
</Location>
Leave a Comment

If you have a suggestion or issue with the above commands, please leave a comment below, or on this Hacker News discussion!