Skip to content

Instantly share code, notes, and snippets.

@GAS85
Last active February 7, 2023 16:17
Show Gist options
  • Save GAS85/990b46a3a9c2a16c0ece4e48ebce7300 to your computer and use it in GitHub Desktop.
Save GAS85/990b46a3a9c2a16c0ece4e48ebce7300 to your computer and use it in GitHub Desktop.
How to Enable HTTP/2 in Apache 2.4 on Ubuntu 16.04

Requirements

  • A self-managed VPS or dedicated server with Ubuntu 16.04 running Apache 2.4.xx.
  • For Ubuntu 18.04 please read here --> https://gist.github.com/GAS85/8dadbcb3c9a7ecbcb6705530c1252831
  • A registered domain name with working HTTPS (TLS/SSL). HTTP/2 only works alongside HTTPS because most browsers, including Firefox and Chrome, don’t support HTTP/2 in cleartext (non-TLS) mode.

Step 1: Upgrade Apache from PPA

Let’s assume you installed Apache from the standard stable Ubuntu repository using apt. When you check your version of apache2 by typing:

  apache2 -v

… You’ll notice that Apache 2.4.18 is the current default version for Ubuntu 16.04. However, you need Apache 2.4.24 or later for compatibility with HTTP/2.

To get a newer version of Apache, you can use the PPA from Ondřej Surý which includes the latest stable release (Apache 2.4.33 at time of writing). Ondřej is a prominent PHP developer in the Debian community, so this PPA is considered safe.

To add the PPA, type:

sudo add-apt-repository ppa:ondrej/apache2

Or, you can add the PPA manually by inserting these lines into /etc/apt/sources.list:

deb http://ppa.launchpad.net/ondrej/apache2/ubuntu xenial main 
deb-src http://ppa.launchpad.net/ondrej/apache2/ubuntu xenial main 

Once the PPA is added, update and upgrade Apache:

sudo apt update
sudo apt upgrade

This will update and upgrade apache2 to Apache 2.4.33+.

Step 2: Tell Apache to use PHP FastCGI

You want to make Apache use a compatible PHP implementation by changing mod_php to php-fpm (PHP FastCGI). If your website or app breaks on FastCGI, you can always revert back to mod_php until further troubleshooting.

Install PHP FastCGI module for PHP 7.0 current default version for Ubuntu 16.04

(replace with “7.4” if desired):
  • Added Repo with latest PHP:
sudo add-apt-repository ppa:ondrej/php
  • Then install it and follow instruction from below with respect of php 7.4 Version.
sudo apt update
sudo apt install php7.4-fpm

sudo apt install php7.0-fpm 

Enable required modules, proxy_fcgi and setenvif:

sudo a2enmod proxy_fcgi setenvif

Enable php7.0-fpm:

sudo a2enconf php7.0-fpm 

Disable the mod_php module:

sudo a2dismod php7.0 

Restart Apache if no errors comes:

sudo service apache2 restart

Step 3: Change MPM from "prefork" to "event"

Since the default "prefork" MPM (Multi-Processing Module) is not fully compatible with HTTP/2, you’ll need to change Apache’s current MPM to "event" (or "worker"). This is shown by the error message in Apache versions greater than 2.4.27 as – AH10034: The mpm module (prefork.c) is not supported by mod_http2.

Keep in mind that your server requires more horsepower for HTTP/2 than for HTTP/1.1, due to the multiplexing feature and other factors. That said, smaller servers with low traffic may not see much difference in performance.

First, disable the "prefork" MPM:

sudo a2dismod mpm_prefork 

Enable the "event" MPM:

sudo a2enmod mpm_event 

Restart Apache and PHP 7.0:

sudo service apache2 restart 

sudo service php7.0-fpm restart

Step 4: Add a line to your Virtual Host file

Add the following line to your site’s current Virtual Host config file. This can go anywhere between the ... tags. If you want to serve HTTP/2 for all your sites, add this to your global /etc/apache2/apache2.conf file instead of per each individual site’s Virtual Host file.

Protocols h2 h2c http/1.1

Explanation: h2 is TLS-encrypted HTTP/2, h2c is cleartext HTTP/2, and http/1.1 is ordinary HTTP/1.1.

Having http/1.1 at the end of the line provides a fallback to HTTP/1.1, while h2c is not strictly necessary.

Step 5: Enable the mod_http2 Apache module

Now you can enable the http2 module in Apache:

sudo a2enmod http2

Restart Apache:

sudo service apache2 restart

Step 6 create http2.conf for entire Server HTTP2

Create a new http2.conf

sudo nano /etc/apache2/conf-available/http2.conf

and add all the following rows:

<IfModule http2_module>
Protocols h2 h2c http/1.1
H2Direct on
</IfModule>

Enable the http2.conf by running

sudo a2enconf http2

Test configuration and restart Apache if no errors comes:

sudo apachectl configtest && sudo service apache2 restart

and enhance your ssl-vhost file (default-ssl.conf):

sudo nano /etc/apache2/sites-available/default-ssl.conf

Amend in your configuration file:

...
Protocols h2 h2c http/1.1
H2Push on
H2PushPriority * after
H2PushPriority text/css before
H2PushPriority image/jpg after 32
H2PushPriority image/jpeg after 32
H2PushPriority image/png after 32
H2PushPriority application/javascript interleaved
...

P.S. All in one command (you still have to edit your VirtualHost and ssl config):

sudo add-apt-repository ppa:ondrej/apache2
sudo apt update
sudo apt upgrade
sudo apt install php7.0-fpm
sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php7.0-fpm
sudo a2dismod php7.0
sudo service apache2 restart
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo service apache2 restart
sudo service php7.0-fpm restart
sudo a2enmod http2
sudo service apache2 restart
sudo echo "<IfModule http2_module>" > /etc/apache2/conf-available/http2.conf
sudo echo "Protocols h2 h2c http/1.1" >> /etc/apache2/conf-available/http2.conf
sudo echo "H2Direct on" >> /etc/apache2/conf-available/http2.conf
sudo echo "</IfModule>" >> /etc/apache2/conf-available/http2.conf
sudo a2enconf http2
sudo apachectl configtest && sudo service apache2 restart
@GAS85
Copy link
Author

GAS85 commented Jun 14, 2019

U welcome!

@bereska
Copy link

bereska commented Oct 15, 2019

thanks for the guide
it just works

@FabianSchmick
Copy link

FabianSchmick commented Mar 11, 2020

You should also update some ini settings in /etc/php/7.0/fpm/php.ini

e.g.:

upload_max_filesize = 32M 
post_max_size = 48M 
memory_limit = 256M 
max_execution_time = 600 
max_input_vars = 3000 

after that restart sudo service php7.0-fpm restart

@GAS85
Copy link
Author

GAS85 commented Mar 11, 2020

You should also update some ini settings in /etc/php/7.4/fpm/php.ini

Basically it is fine-tuning and not necessary to enable http2 per default. It is strongly depends on your HW and Applications on it.
Small tip by restart you have to specify php Version, in your case it seems php7.4-fpm instead of php7.0-fpm.

@FabianSchmick
Copy link

Yes you are right, it is fine-tuning. But after switching over to fpm I forgot the settings I did before, so I thought it is worth mentioning it. Ops I corrected the path so it matches with your instructions.

@GAS85
Copy link
Author

GAS85 commented Mar 11, 2020

@FabianSchmick Thanks!

@p637
Copy link

p637 commented Apr 26, 2020

hi, thanks for your job. just installed on 16.04 and working fine for my website. The only isssue is with zoneminder, a surveillance famous program. In ZM there is a view in which it is possible to see more cameras. In this view after some times some cameras disappears and I have to close and reopen the page. I tested: removing h2 from Protocols in Virtual Host, the issue disappear since Apache working only in http1.1. is it a bug? thanks

@p637
Copy link

p637 commented Apr 26, 2020

Solved the issue, updated as suggested the php.ini file adding at the bottom:

upload_max_filesize = 32M
post_max_size = 48M
memory_limit = 256M
max_execution_time = 600
max_input_vars = 3000

could you explain why solved?
perfect. thanks you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment