{"id":159,"date":"2023-11-11T20:40:38","date_gmt":"2023-11-11T18:40:38","guid":{"rendered":"https:\/\/www.contentecontent.com\/blog\/?p=159"},"modified":"2023-11-11T20:53:15","modified_gmt":"2023-11-11T18:53:15","slug":"enabling-php-fpm-and-http-2-on-apache2","status":"publish","type":"post","link":"https:\/\/www.contentecontent.com\/blog\/2023\/11\/enabling-php-fpm-and-http-2-on-apache2\/","title":{"rendered":"Enabling PHP-FPM and HTTP\/2 on Apache2"},"content":{"rendered":"<p>Something I&#8217;ve wanting to do a long time but never got around to: enabling HTTP\/2 on my Apache webserver. <a href=\"https:\/\/en.wikipedia.org\/wiki\/HTTP\/2\" rel=\"noopener\" target=\"_blank\">HTTP\/2<\/a> has been around for over 8 years now. It is supposed to be faster and cooler, and by now almost every browser out there supports it.<\/p>\n<p>In my case it also meant switching setups for Apache and PHP. Apache&#8217;s http2-module doesn&#8217;t run on mpm_prefork; but mpm_prefork is required by Apache&#8217;s PHP module. (MPM: multiprocessing module, the way Apache receives and processes requests. Prefork is one MPM type, event and worker are others.) So I needed to switch from mpm_prefork to mpm_event and from mod_php to PHP-FPM.<\/p>\n<p>Thanks to the handy commands <code>a2enmod<\/code> and <code>a2dismod<\/code> commands changing the setup is quite easy.<\/p>\n<p>First install PHP-FPM:<\/p>\n<pre>sudo apt install php7.4-fpm<\/pre>\n<p>(yes I know that is a very old PHP version &#8230;)<\/p>\n<p>Then disable and enable modules:<\/p>\n<pre>sudo a2dismod php7.4 mpm_prefork\nsudo a2enmod mpm_event proxy_fcgi http2<\/pre>\n<p>Make sure to also enable the <code>setenvif<\/code> module if you hadn&#8217;t already done that. I ran <code>sudo a2enconf php7.4-fpm<\/code> as well, not sure whether that is required though.<\/p>\n<p>Finally, restart Apache:<\/p>\n<pre>sudo service apache2 restart<\/pre>\n<p>I tried this first on a Debian server running on Windows WSL, and it worked perfectly well. I was slightly worried that &#8220;the new Apache&#8221; might run as a different user, but that turned out not be the case (saving me from chown-ing many, many files). Then, on the server you&#8217;re looking at I backed-up the \/etc\/apache2 folder and ran the same commands. This time restarting Apache threw an error:<\/p>\n<pre>Job for apache2.service failed because the control process exited with error code.\nSee \"systemctl status apache2.service\" and \"journalctl -xe\" for details.<\/pre>\n<p>None of the suggestions provided anything useful, so I had to quickly roll back the changes.<\/p>\n<pre>sudo a2dismod mpm_event proxy_fcgi http2\nsudo a2enmod php7.4 mpm_prefork\nsudo service apache2 restart<\/pre>\n<p>Time to scan the logs. There was nothing in Apache&#8217;s own error.log, but fortunately syslog came to the rescue:<\/p>\n<pre>Syntax error on line 8 of \/etc\/apache2\/sites-enabled\/some-site.conf:\nInvalid command 'php_admin_value', perhaps misspelled or defined by a module not included in the server configuration.<\/pre>\n<p>Turns out that <code>php_admin_value<\/code>, <code>php_value<\/code> and <code>php_flag<\/code> are only recognized by mod_php, not by PHP-FPM. I was using some of them for setting things like <code>upload_max_filesize<\/code> and <code>post_max_size<\/code>, in vhosts and in .htaccess. But PHP-FPM <em>does<\/em> support .user.ini-files. So I created a bunch of such files and put them in the web roots of the affected sites. For a smooth transition I put the old vhost\/htaccess commands in conditional blocks, like this:<\/p>\n<pre>&lt;IfModule mod_php7.c&gt;\n    php_value post_max_size 9M\n    php_value upload_max_filesize 8M\n&lt;\/IfModule&gt;<\/pre>\n<p>Disable and enable the modules again:<\/p>\n<pre>sudo a2dismod php7.4 mpm_prefork\nsudo a2enmod mpm_event proxy_fcgi http2<\/pre>\n<p>This time I tested the new config with <code>sudo apachectl -t<\/code>. &#8220;Syntax OK&#8221;! So, fingers crossed:<\/p>\n<pre>sudo service apache2 restart<\/pre>\n<p>Voil\u00e0.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Something I&#8217;ve wanting to do a long time but never got around to: enabling HTTP\/2 on my Apache webserver. HTTP\/2 has been around for over 8 years now. It is supposed to be faster and cooler, and by now almost every browser out there supports it. In my case it also meant switching setups for &hellip; <a href=\"https:\/\/www.contentecontent.com\/blog\/2023\/11\/enabling-php-fpm-and-http-2-on-apache2\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Enabling PHP-FPM and HTTP\/2 on Apache2<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-159","post","type-post","status-publish","format-standard","hentry","category-server-admin"],"_links":{"self":[{"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/posts\/159","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/comments?post=159"}],"version-history":[{"count":10,"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/posts\/159\/revisions"}],"predecessor-version":[{"id":169,"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/posts\/159\/revisions\/169"}],"wp:attachment":[{"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/media?parent=159"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/categories?post=159"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.contentecontent.com\/blog\/wp-json\/wp\/v2\/tags?post=159"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}