The HTTP/2 network protocol already has a very good support since it was officially published in May 2015. It is great because it brings many benefits over HTTP/1.1 which include multiplexing, server-push, streaming prioritization, etc. This means that websites load faster because the resources get grouped in a single connection.
You can verify if a website is using HTTP/2 with the command line. For example,
using the widely available curl
command:
curl -I https://www.google.com
It will print the protocol in the first line of the output:
HTTP/2 200
content-type: text/html; charset=ISO-8859-1
...
This means that the website supports using HTTP/2. You can also check the
protocol in Chrome's devtools, in the network tab, where you can add the
"Protocol" column for each request. If it prints h2
, it means that it is
requesting the resource using HTTP/2.
If you have to set up a server with Apache and it is using reverse proxies to Docker containers, (which complicate it), you can get some tips here for what to change.
I will assume that there is an Apache server already configured to support HTTPS
requests (by using SSLEngine on
). This Apache server is in a Docker container
within a Docker Compose network, and is the entry point for the requests.
First of all we have to enable the module in the Apache's site configuration:
LoadModule http2_module modules/mod_http2.so
This will load the core Apache module, but if you are also using reverse proxies like in this case, it also requires to use an additional module:
LoadModule proxy_http2_module modules/mod_proxy_http2.so
In Ubuntu systems you can enable the module with the a2enmod
command.
Once the module has been loaded, you have to specify the protocols that the site can support:
Protocols h2 http/1.1
The order is important, it will give preference from left to right, starting
from h2
if supported, then h2c
(the unencrypted version) and then fallback
to http/1.1
.
We can define two reverse proxies to peer containers in the docker network with these lines:
ProxyPass /api h2c://api:5000
ProxyPassReverse /api http://api:5000
ProxyPass / h2c://static-site/
ProxyPassReverse / http://static-site/
Here it is using h2c
because the internal containers don't have encryption.
The reverse directive can use http
directly. If you have to proxy to sevices
using SSL, you will have to enable SSLProxyEngine
from mod_ssl
but that is
not covered in this tutorial.
You can read more about the h2c
properties in the Apache
http2 and
proxy_http2
modules docs.
We can't forget to also enable HTTP/2 in the proxied services, otherwise we
will encounter a 503
response code when requesting our site because the
proxied services can't handle the request.
If the proxied container is also using Apache, for example let's imagine that
the container handling http://static-site/
in the block above is, it will be
necessary to update the configuration in that container too. In this case it
doesn't need the h2
protocol since the requests are proxied using h2c
, so
the changes would be:
LoadModule http2_module modules/mod_http2.so
# ...
Protocols h2c http/1.1
Now you can restart the Apache server in the containers for the configuration to take effect, and you should see that the clients start to use HTTP/2. This is a big benefit, which will improve loading times and also SEO for your website.