How to Enable HTTP/2 Protocol with Apache on Ubuntu 16.04/17.10

This tutorial is going to show you how to enable HTTP/2 protocol and use server push with Apache on Ubuntu 16.04 and Ubuntu 17.10. As you may know, HTTP/2 is way faster than HTTP/1.1 protocol, mainly because the former enables web browser to send multiple requests to web server at the same time on a single TCP connection, which is known as multiplexing, and receive responses out of order.

Nowadays the average Internet user’s bandwidth is much higher than before, which helps with loading web pages faster. However, after bandwidth reaches 5Mbps, it has little impact on page load time. Whether you are using 5Mbps or 10Mbps, web pages are loaded nearly in the same amount of time. Now what can greatly affect page load times are latency and the number of round trips. That is one of the problems HTTP/2 multiplexing solves.

Prerequisites

HTTP/2 specification allows plain text HTTP, but in practice all main stream web browsers implement HTTP/2 in a way that requires HTTPS. We can obtain free SSL certificates from Let’s Encrypt, please see my previous tutorial: how to properly enable HTTPS on Apache with Let’s Encrypt on Ubuntu 16.04/17.10.

HTTP/2 in Apache is production-ready starting with version 2.4.26. So you will need Apache 2.4.26 or above built with mod_http2, the Apache HTTP/2 module. The Apache package in Ubuntu 16.04 and Ubuntu 17.10 comes with no HTTP/2 module. You can install the latest version of Apache with mod_http2 from ondřej surý‘s PPA. This guy is also the maintainer of Certbot PPA.

sudo apt install software-properties-common

sudo add-apt-repository ppa:ondrej/apache2

sudo apt update

sudo apt install apache2

Enable HTTP/2 Protocol on Apache Virtual Host

Once you meet the above two requirements, you can enable the HTTP/2 module.

sudo a2enmod http2

Then edit your Apache virtual host file. If you enabled HTTPS with Let’s Encrypt, then the SSL virtual host is defined a separate file ending with le-ssl.conf.

sudo nano /etc/apache2/sites-enabled/your-site-le-ssl.conf

Put the following directive after the opening <VirtualHost *:443> tag.

Protocols h2 http/1.1

apache http2

Save and close the file. Then restart Apache for the changes to take effect.

sudo systemctl restart apache2

If you are using mod_php

If you use mod_php module with Apache, then you are using prefork MPM module. Unfortunately Mod_http2 does not support prefork.  You can use the event MPM module in order to support HTTP/2 and that requires you to run PHP with FastCGI because event MPM is not compatible with mod_php.  Follow the steps below to switch from prefork to event MPM. Note that in the following commands php7.0 is used on Ubuntu 16.04 and PHP7.1 used on Ubuntu 17.10.

Disable PHP7 module.

sudo a2dismod php7.0  

sudo a2dismod php7.1

Disable prefork MPM module.

sudo a2dismod mpm_prefork

Enable Event MPM, Fast_CGI and setenvif module.

sudo a2enmod mpm_event proxy_fcgi setenvif

Install PHP-FPM

sudo apt install php7.0-fpm 

sudo apt install php7.1-fpm

Start PHP-FPM

sudo systemctl start php7.0-fpm

sudo systemctl start php7.1-fpm

Enable PHP-FPM to start at boot time.

sudo systemctl enable php7.0-fpm

sudo systemctl enable php7.1-fpm

Set PHP-FPM as Apache’s PHP handler using the following command, which will enable /etc/apache2/conf-available/php7.x-fpm .conf file.

sudo a2enconf php7.0-fpm

sudo a2enconf php7.1-fpm

Restart Apache for the changes to take effect.

sudo systemctl restart apache2

Test

How do you know your site is actually using HTTP2 protocol?

  • In Firefox or Google Chrome, load a page of your site, then press Ctrl+Shift+I to open Developer Tools, click the Network tab. You can see the protocol being used for your domain.
  • You can also install the HTTP/2 and SPDY Indicator extension in Google Chrome.
  • Install the HTTP/2 Indicator extension in Firefox.
  • The online HTTP/2 test tool by KeyCDN can tell you if HTTP/2 and ALPN is supported on your site.

Note that you may need to clear your browser’s cache because cached objects may be mistakenly marked with HTTP/1.1 protocol.

http2 apache ubuntu

How to Enable Server Push

HTTP/2 comes with a feature called “server push”, which allows web server to send resources that the web browser didn’t ask for, but is needed for loading web pages. For example, if web browser requests a HTML document, then the web server knowns that the client will need the associated CSS file and send it along with HTML document, thus eliminating the need for web browser to send the request for CSS, so one round trip is reduced.

Here, I use WordPress as an example. The following resources are commonly needed for WordPress site.

  • style.css: the main stylesheet, located in the root of theme directory.
  • jquery.js: JQuery libary
  • jquery-migrate.min.js: the old JQuery
  • wp-embed.min.js: for embedding videos

To push these resources to clients, add the following directives in <VirtualHost> block. Replace twentyseventeen with your own WordPress theme name.

Header add Link "</wp-content/themes/twentyseventeen/style.css>;rel=preload"
Header add Link "</wp-includes/js/jquery/jquery.js>;rel=preload"
Header add Link "</wp-includes/js/jquery/jquery-migrate.min.js>;rel=preload"
Header add Link "</wp-includes/js/wp-embed.min.js>;rel=preload"

Save and close the file. Then restart Apache for the changes to take effect.

sudo systemctl restart apache2

Note that you need to add the following code in functions.php file to remove version number from WordPress CSS and JavaScript files. When WordPress updates, server push won’t work if version number is added to these files.

// Remove WP Version From Styles        
add_filter( 'style_loader_src', 'sdt_remove_ver_css_js', 9999 );
// Remove WP Version From Scripts
add_filter( 'script_loader_src', 'sdt_remove_ver_css_js', 9999 );

// Function to remove version numbers
function sdt_remove_ver_css_js( $src ) {
        if ( strpos( $src, 'ver=' ) )
                $src = remove_query_arg( 'ver', $src );
        return $src;
}

Testing Server Push

In Google Chrome browser, load your page, then press Ctrl+Shift+I to open developer tools and click Network tab. Press F5 to reload. As you can see from the screen shot below, server push is working on one of my websites. If you see “from memory cache”, then right-click on it, clear browser cache and reload.

ubuntu 16.04 apache http2

That’s it! I hope this tutorial helped you enable HTTP/2 in Apache on Ubuntu 16.04/17.10 and use server push. As always, if you found this post useful, then subscribe to our free newsletter.

Rate this tutorial
[Total: 1 Average: 5]