Hypertext Transfer Protocol Version 2 (HTTP/2) is the latest version of the HTTP protocol, published as an IETF standard in RFC 7540 in 2015. The focus of the protocol is on performance; specifically, end-user perceived latency, network, and server resource usage. One major goal is to allow the use of a single connection from browsers to a Web site. The protocol is backward compatible, so HTTP methods, status codes, and semantics are the same as for previous versions of the protocol. Apache has HTTP/2 support since version 2.4.17.  In this tutorial, I’m going to assume that you already have a working TLS configuration, and that you have the required Apache version installed on your Linux distribution of choice, and that you know how to use Let’s Encrypt, or you know how to issue a self-signed certificate.

This tutorial has been tested on Debian 10, Debian 9, Ubuntu 20.04 LTS, and Ubuntu 18.04 LTS.

Prerequisites

To enable HTTP/2 in Apache you will need to fulfill the following requirements:

  • First, you need to enable HTTPS on your server. All major browsers allow using HTTP/2 only over HTTPS. AlsoTLS protocol version >= 1.2 with modern cipher suites is required.
  • Next, ensure that you are running Apache 2.4.17 or above because HTTP/2 is supported from this version and upwards.
  • Also, ensure that your client/browser actually supports HTTP/2.

Disable the mod_php module

Before we can switch the Apache MPM module in the next step to mpm_event, we will have to disable the old mod_php mode and replace it with the more modern PHP-FPM mode. The commands differ for each Operating system version, please use the ones that match your installed system.

Ubuntu 20.04 LTS

sudo apt-get install php7.4-fpm

sudo a2dismod php7.4

sudo a2enconf php7.4-fpm

sudo a2enmod proxy_fcgi

Debian 10

sudo apt-get install php7.3-fpm

sudo a2dismod php7.3

sudo a2enconf php7.3-fpm

sudo a2enmod proxy_fcgi

Ubuntu 18.04 LTS

sudo apt-get install php7.2-fpm

sudo a2dismod php7.2

sudo a2enconf php7.2-fpm

sudo a2enmod proxy_fcgi

Debian 9

sudo apt-get install php7.0-fpm

sudo a2dismod php7.0

sudo a2enconf php7.0-fpm

sudo a2enmod proxy_fcgi

Enable an Apache MPM that is compatible with HTTP/2

By default, Apache will use the prefork MPM. This MPM is not compatible with HTTP/2, so we will have to replace it with the more modern mpm_event module.

First, we disable mpm_prefork module:

sudo a2dismod mpm_prefork

Then we enable the mpm_event module:

sudo a2enmod mpm_event

Enable HTTP/2 support in Apache

To get HTTP/2 working on Apache you need to enable and load SSL and HTTP/2 modules. To do so, you may run the following in your terminal:

sudo a2enmod ssl

and then

sudo a2enmod http2

To activate these new modules, you need to run:

sudo systemctl restart apache2

After enabling and loading necessary Apache modules, navigate to your Apache configuration directory and edit Apache configuration.

To enable HTTP/2 on your Apache web server add one of the following to your global Apache configuration or inside of a particular virtual host.

Protocols h2 http/1.1

Here is the minimal virtual server configuration that can be used to enable HTTP/2 in some virtual host:

<VirtualHost *:443>

ServerName example.com

ServerAlias www.example.com

DocumentRoot /var/www/public_html/example.com

SSLEngine on

SSLCertificateKeyFile /path/to/private.pem

SSLCertificateFile /path/to/cert.pem

SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1

Protocols h2 http/1.1

</
VirtualHost>

To check if your server supports HTTP/2, you can use your browser dev tools. The below are screenshots from Google Chrome and Apple Safari browsers that show HTTP/2 in action on https://example.com domain.

Chrome

<img alt="HTTP/2 in Chrome Browser" data-ezsrc="https://kirelos.com/wp-content/uploads/2022/09/echo/http2.png631064917c10e.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="428" loading="lazy" src="data:image/svg xml,” width=”750″>

Safari

<img alt="HTTP/2 in Safari Browser" data-ezsrc="https://kirelos.com/wp-content/uploads/2022/09/echo/http2-safari-browser.png631064923dced.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="431" loading="lazy" src="data:image/svg xml,” width=”750″>