How to Enable HTTP/2 Protocol with Apache on Ubuntu 20.04
This tutorial is going to show you how to enable HTTP/2 protocol and use server push with Apache on Ubuntu 20.04. As you may know, HTTP/2 is way faster than HTTP/1.1 protocol, mainly because the former enables a web browser to send multiple requests to web server at the same time on a single TCP connection (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. These days, 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 mainstream web browsers implement HTTP/2 in a way that requires HTTPS. So before enabling HTTP/2 protocol, you need to enable HTTPS on your website. You can read the following detailed guide to enable HTTPS
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. Ubuntu 20.04 comes with Apache 2.4.41, which can be checked with:
apache2 -v
Sample output:
Server version: Apache/2.4.41 (Ubuntu) Server built: 2020-04-13T17:19:17
Once you meet the above two requirements, follow the instructions below to enable HTTP/2 in Apache.
Enable HTTP/2 Protocol on Apache Virtual Host
First, you need to 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 created as 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
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.
Disable PHP7 module.
sudo a2dismod php7.4
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.4-fpm
Start PHP-FPM
sudo systemctl start php7.4-fpm
Enable PHP-FPM to start at boot time.
sudo systemctl enable php7.4-fpm
Set PHP-FPM as Apache’s PHP handler using the following command, which will enable /etc/apache2/conf-available/php7.4-fpm .conf
file.
sudo a2enconf php7.4-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.
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.
Note
When you upgrade Apache or the operating system, it might install a new version of Apache PHP module and disable HTTP/2 automatically. You need to follow the above instructions to disable mod_php again to re-enable HTTP/2.
Next Step
That’s it! I hope this tutorial helped you enable HTTP/2 in Apache on Ubuntu 20.04 and use server push. You may also want to set up ModSecurity web application firewall to protect your site from hacking.
As always, if you found this post useful, then subscribe to our free newsletter.
Thanks a lot this solve my http2 issue
Glad to know it’s working for you 🙂
Followed your tutorial now the http2 is working but the redis is not working and i can’t reverse the process. Is there any other way to use both http2 and redis.
I just installed a new Nextcloud instance with Apache web server. There’s no conflict between Redis and HTTP/2. You can try applying the Redis instructions again to see if it will work.
Hi there,
I had been tearing my hair out with this, but your prefork process worked perfectly. Thanks!