http2 and Apache prefork mpm

Hello!
Debian has just upgraded its Apache package to 2.4.25-3+deb9u5. With the upgrade, an Apache server running with mpm_prefork will no longer support http2. I have been using prefork for many years and don't know much about the other available mpms, though I understand they don't support the Apache's PHP7 module. Can someone point me towards either:

  1. a workaround to allow http2 without changing the mpm; or
  2. a method for changing the mpm that allows me to keep using PHP?

Thank you!

4 Replies

After I saw the changelog, I decided to switch to php-fpm, mod_proxy, mod_proxy_fcgi and the event MPM on a test server running Stretch, to see how it would go. It seems to have gone well. And HTTP2 works again.

Other than installing/removing stuff and enabling/disabling mods and conf files, the only manual thing I had to do was copy my user settings to a place where fpm can see them.

I plan to do some research in the next week or two to get a better grasp of the whole thing and I will post my findings here.

Thanks Demetris! That is helpful--I will look forward to reading your findings.

I just completed the switch from mod_php to PHP-FPM on a second server running Debian Stretch. I think everything works well on the second server too.

Here are the steps I took along with a few notes.

Two preliminary notes

First, with PHP-FPM we cannot use PHP directives in Apache config files and .htaccess files. In PHP-FPM such directives are not only ineffective; they also cause configuration errors.

For this reason, it is a good idea to check for such directives before starting the switch from mod_php to PHP-FPM, remove them (or comment them out), and take a note of them so that we know what we may need to add to our PHP-FMP user configuration after the switch is complete (see last part: PHP user configuration).

Second, other than removing (or commenting out) PHP directives, no other change seems to be necessary in Apache conf files and .htaccess files. Redirection to PHP-FMP is taken care by the default Apache PHP-FPM conf file, which you are asked to enable during the installation.

The path to this default conf file is /etc/apache2/conf-available/php7.x-fpm.conf.

Its content is this:

# Redirect to local php-fmp is mod_php is not available
<IfModule !mod_php7.c>
  <IfModule proxy_fcgi_module>

    # Enable http authorization headers  
    <IfModule setenvif_module>   
      SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1  
    </IfModule>  

    <FilesMatch ".+\.ph(p[3457]?|t|tml)$"> 
      SetHandler "proxy:unix:/run/php/php7.0-fpm.sock|fcgi://localhost"
    </FilesMatch>

    # Deny access to raw php sources by default
    # To re-enable it's recommended to enable access to the files    
    # only in specific virtual host or directory
    <FilesMatch ".+\.phps$">
      Require all denied 
    </FilesMatch>

    # Deny access to files without filename (e.g. '.php')
    <FilesMatch "^\.ph(p[3457]?|t|tml|ps)$">
      Require all denied 
    </FilesMatch>
  </IfModule>
</IfModule>

Now, let’s start the switch!

The steps for switching

sudo apt remove libapache2-mod-php*

Here, since we are removing mod_php, apt will likely ask to install PHP-FPM automatically. If it does not, we do it manually:

sudo apt install php7.0-fpm

After PHP-FPM is installed, we are given instructions to enable/disable Apache mods and conf files. We execute three commands:

sudo a2dismod php7.0 mpm_prefork

sudo a2enmod proxy proxy_fcgi mpm_event setenvif

sudo a2enconf php7.0-fmp

Note that, since we started by uninstalling mod_php, the first command will probably do nothing (php7.0 and mpm_prefork, which can be used only with mod_php, should be already disabled and removed by now).

Finally, we restart Apache and PHP-FPM:

sudo systemctl restart apache2 php7.0-fpm

Done!

PHP user configuration

When using mod_php, I like to put my user settings for PHP in a file in /etc/php/7.x/apache2/conf.d. I name this file 50-user.ini, so that it is loaded after everything else in conf.d.

For PHP-FPM, I put this file into /etc/php/7.x/fpm/conf.d.

In addition to general directives, INI files in PHP-FPM also support directives for specific hosts or paths. Here is a sample from the directives I use in my user INI file for PHP-FPM:

post_max_size = 64M
upload_max_filesize = 64M
user_ini.filename = ""

[opcache]
opcache.max_accelerated_files=16229
opcache.memory_consumption=256

[path=/path/to/website-files/public]
open_basedir = /path/to/website-files/public:/tmp

[host=example.com]
open_basedir = /path/to/example.com/public
upload_tmp_dir = /path/to/example.com/public/tmp

To activate changes in our PHP configuration, we reload the PHP-FPM service:

sudo systemctl reload php7.0-fpm

Note that this is different to what we do when using mod_php (reloading the apache2 service), since PHP is no longer part of Apache.

Cheers!

@demetris, thanks for this! I have been able to make the switch--it required a little bit of tinkering, e.g., I had to remove all php_basedir directives from my virtual host files. But your method works.

I am still having one difficulty. It seems to me that the rewrite rules in my .htaccess file no longer work. So on my wordpress site, the home page displays correctly, but if I click on a link to a post (which has a URL like this https://mysite.com/2018/08/05/postname), the page does not load. My .htaccess file has the following rewrite rules, which I think are standard in wordpress.

<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>

(There is more in the .htaccess file, of course).

Thoughts?

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct