Enabling apache2 HTTP/2 in ubuntu server

Submitted by oioioooi on 08/01/2022 - 17:10

The article describes on how to make use of HTTP/2 protocol in Apache2 when serving web content.

HTTP/2 comes as a replacement for HTTP/1.1, that allows multiple resources requested within same connection. In the older variant, HTTP/1.1, each resource (stylesheet, image, script) is loaded during one single request. That is, each resource is loaded one after another and the number of such requests that browser can initiate within a specific timespan is limited. Whether there is a large number of resources to be loaded, the requests are put in a queue and performed one after another.

HTTP/2 solves this issue, by using the stream approach. A stream enables a bi-directional communication, where several streams can run within same connection. This allows to request and fetch several resources simultaneously. This is way different in comparison to older HTTP/1.1 approach, where each connection is a single pair of a request/response.

All modern browsers support HTTP/2, so there's no reason not using it: https://caniuse.com/?search=http2

All modern web-servers also support HTTP/2, however this article aims towards Apache2.

To enable HTTP/2, we must enable the respective apache module:

$ sudo a2enmod http2

Next, edit the Apache's confiuration file to instruct serving content over HTTP/2:

Protocols h2 h2c http/1.1

This directive can be applied globally, in the apache2.conf file, or per virtual host, inside respective <VirtualHost> block.

Some notes on the directive above:

  • h2 - it's the HTTP2 protocol itself, served over TLS;
  • h2c - HTTP2 protocol, usable outside the browser, server over TCP;
  • http/1.1 - older http/1.1 fallback;

Protocols are served left to right, so apache2 will attempt to serve h2 first.

The difference between h2 and h2c is that h2 is used primarily by the browsers. A website can access https websites only via SSL which is is encrypted traffic and nothing else. h2c allows cleartext https access, mainly useful for usage via non-browser http clients, like curl.

Restart apache:

$ sudo /etc/init.d/apache2 restart

In order to check whether the browser queries the server via HTTP/2, open the developer tools (hit F12), switch to Network tab and observe the Protocol column (add the one if it's not present, by right-clicking on any column and selecting Protocol from the list).

network-http2

There is already HTTP3 spec, which is, unfortunately, not yet supported by Apache2. Major browsers, on the other hand, partially do have support for HTTP/3 support: https://caniuse.com/?search=http3

When serving PHP via Apache2, the most common way of doing so is the apache2 module - mod-php. This way of serving PHP files would not work over HTTP/2 because of how this module integrates with Apache2 (read more about Apache2 MPM's). Simply put, this module is not async, so best would be to switch to PHP-FPM approach, as this way of serving dynamic content has other useful features.

As usual, follow the official documentation for details: https://httpd.apache.org/docs/2.4/howto/http2.html

Tags