Difference between revisions of "PHP"

From Jon's Wiki
(Created page with "There's a lot of talk about using Nginx instead of Apache, and for some things it's probably easier to configure or maintain, especially if you're writing IaC, but some things...")
 
 
(14 intermediate revisions by the same user not shown)
Line 1: Line 1:
 +
: ''These instructions assume Ubuntu LTS (currently 20.04, c. August 2021) and are easily adapted to a Docker or other container definition, Ansible playbook, etc.''
 +
 
There's a lot of talk about using Nginx instead of Apache, and for some things it's probably easier to configure or maintain, especially if you're writing IaC, but some things still assume or prefer Apache, particularly in PHP land. WordPress and NextCloud are example PHP applications that want to modify their {{code|.htaccess}} files in-place, for example to keep up with security developments.
 
There's a lot of talk about using Nginx instead of Apache, and for some things it's probably easier to configure or maintain, especially if you're writing IaC, but some things still assume or prefer Apache, particularly in PHP land. WordPress and NextCloud are example PHP applications that want to modify their {{code|.htaccess}} files in-place, for example to keep up with security developments.
  
These instructions assume Ubuntu LTS (currently 20.04, c. August 2021) and are easily adapted to a Docker or other definition.
+
Perhaps part of the reason for the currently fashionable dim view of Apache's performance is that PHP is often run in production using mod-php, which ''at best'' should only be used on a development workstation, if at all. Apart from being incompatible with HTTP/2, it is a CPU and memory hog, since it can only run using Apache's horribly inefficient prefork multi-process management (MPM). Apache has several modules for dealing with MPM, but can only have one MPM module enabled at a time. Other much better, multithreaded, more efficient and fast MPM modules have been around for nearly two decades, and since version 5.4 of PHP (late 2011) we can use Apache's Event MPM and FastCGI modules with PHP-FPM. More information is available on the Apache [https://cwiki.apache.org/confluence/display/httpd/PHP-FPM httpd wiki].
  
That said, running Apache using mod-php should only be used on a development workstation, if at all. Apart from being incompatible with HTTP/2, it is a CPU and memory hog, since it can only run using Apache's horribly inefficient prefork MPM worker. Apache has several ways to deal with multi-process management (MPM), but can only run one scheme at a time. There are other much better, more modern, multithreaded and very fast MPM workers, and luckily these days we can use Apache's Event MPM and FastCGI modules with PHP-FPM, which has been built-in since version 5.4 of PHP.
+
With PHP processes being handled much more efficiently, and by being able to finally enable HTTP/2 in Apache, it all actually goes like the clappers.
  
 
== Prerequisites ==
 
== Prerequisites ==
  
Install some stuff first. To support NextCloud for example, this Apache PHP recipe also uses [[PostgreSQL]], Redis, FastCGI with PHP FPM, and Dehydrated for managing [[Letsencrypt]] SSL certificates.
+
Install at least the following packages:
 +
 
 +
sudo apt install apache2 libapache2-mod-fcgid php-fpm php7.4-{fpm,opcache}
 +
 
 +
You'll need various PHP extensions to host a real PHP application; for example [[NextCloud]] requires PHP composer, [[PostgreSQL]], Redis, and Dehydrated is useful for managing [[Letsencrypt]] SSL certificates.
  
  sudo apt install apache2 libapache2-mod-fcgid \
+
  sudo apt install php-{imagick,redis} \
    php7.4-{bcmath,bz2,curl,gd,fpm,gmp,intl,json,mbstring,opcache,pgsql,soap,tidy,xmlrpc,xsl,zip}
+
    php7.4-{bcmath,bz2,curl,gd,gmp,intl,json,mbstring,pgsql,soap,tidy,xmlrpc,xsl,zip} \
    php-{fpm,imagick,redis} composer dehydrated postgresql redis-server
+
    composer postgresql redis-server dehydrated
  
 
== Set up Apache ==  
 
== Set up Apache ==  
Line 18: Line 24:
  
 
  a2enconf php7.4-fpm
 
  a2enconf php7.4-fpm
  a2enmod dir env headers mpm_event proxy_fcgi rewrite setenvif ssl
+
  a2enmod dir env headers http2 mpm_event proxy_fcgi rewrite setenvif ssl
 
  systemctl restart apache2
 
  systemctl restart apache2
  
Line 28: Line 34:
  
 
  ''# /etc/apache2/conf-available/deny-git.conf''
 
  ''# /etc/apache2/conf-available/deny-git.conf''
  RedirectMatch 404 "/\.(git|hg|bzr|svn|cvs|tag|ht)"
+
  <LocationMatch "/\.(git|hg|bzr|svn|cvs|tag|ht)">
 +
  # Old apache:
 +
  # Order deny,allow
 +
  # deny from all
 +
  Require all denied
 +
</LocationMatch>
  
 
Then enable it with:
 
Then enable it with:
  
 
  a2enconf deny-git
 
  a2enconf deny-git
  systemctl restart apache2
+
  systemctl reload apache2
  
 
=== Add a virtual host ===
 
=== Add a virtual host ===
Line 52: Line 63:
 
   SSLCertificateFile ...
 
   SSLCertificateFile ...
 
  </VirtualHost>
 
  </VirtualHost>
 +
 +
See the [[Letsencrypt]] page for how to sort out your SSL certificates on pet servers.
  
 
== Configure PHP ==
 
== Configure PHP ==
Line 59: Line 72:
 
You will not be able to use mod-php {{code|php_value}} directives in Apache configuration; either try and do without, or set environment variables instead.
 
You will not be able to use mod-php {{code|php_value}} directives in Apache configuration; either try and do without, or set environment variables instead.
  
PHP works a lot better with a few extra things configured. Enable the opcache, increase the memory limit, and depending on what you're hosting, increase the maximum POST size so users can upload photos and other large files. Fiddle with these settings in {{code|/etc/php/7.4/fpm/php.ini}}:
+
PHP works a lot better with a few extra things configured. Enable the opcache, increase the memory limit, and depending on what you're hosting, increase the maximum POST size so users can upload photos and other large files. Other fun helpful things include using Redis for PHP sessions, and tuning the FPM process parameters to make stuff more efficient under load.
 +
 
 +
=== Keep your PHP custom settings and tweaks separate ===
 +
 
 +
Since Debian now moves files around with each new version of PHP, you can keep your customisations to the {{code|php.ini}} file in a local configuration. For example, instead of editing {{code|/etc/php/7.4/fpm/php.ini}}, put these settings in {{code|/etc/php/local/php.ini}}:
  
 +
; /etc/php/local/php.ini
 +
; Override settings in the dist php.ini here
 +
; make a symbolic link to this file in /etc/php/''<version>''/fpm/conf.d/99-local.ini
 
  max_execution_time = 60
 
  max_execution_time = 60
 
  memory_limit = 512M
 
  memory_limit = 512M
Line 67: Line 87:
 
  opcache.enable=1
 
  opcache.enable=1
  
Other fun helpful things include using Redis for PHP sessions, and tuning the FPM process parameters to make stuff more efficient under load.
+
Then we add a symbolic link in the {{code|conf.d}} directory where you need it, for example:
 +
 
 +
ln -s /etc/php/local/php.ini /etc/php/7.4/fpm/conf.d/99-local.ini

Latest revision as of 21:27, 19 May 2023

These instructions assume Ubuntu LTS (currently 20.04, c. August 2021) and are easily adapted to a Docker or other container definition, Ansible playbook, etc.

There's a lot of talk about using Nginx instead of Apache, and for some things it's probably easier to configure or maintain, especially if you're writing IaC, but some things still assume or prefer Apache, particularly in PHP land. WordPress and NextCloud are example PHP applications that want to modify their .htaccess files in-place, for example to keep up with security developments.

Perhaps part of the reason for the currently fashionable dim view of Apache's performance is that PHP is often run in production using mod-php, which at best should only be used on a development workstation, if at all. Apart from being incompatible with HTTP/2, it is a CPU and memory hog, since it can only run using Apache's horribly inefficient prefork multi-process management (MPM). Apache has several modules for dealing with MPM, but can only have one MPM module enabled at a time. Other much better, multithreaded, more efficient and fast MPM modules have been around for nearly two decades, and since version 5.4 of PHP (late 2011) we can use Apache's Event MPM and FastCGI modules with PHP-FPM. More information is available on the Apache httpd wiki.

With PHP processes being handled much more efficiently, and by being able to finally enable HTTP/2 in Apache, it all actually goes like the clappers.

Prerequisites

Install at least the following packages:

sudo apt install apache2 libapache2-mod-fcgid php-fpm php7.4-{fpm,opcache}

You'll need various PHP extensions to host a real PHP application; for example NextCloud requires PHP composer, PostgreSQL, Redis, and Dehydrated is useful for managing Letsencrypt SSL certificates.

sudo apt install php-{imagick,redis} \
    php7.4-{bcmath,bz2,curl,gd,gmp,intl,json,mbstring,pgsql,soap,tidy,xmlrpc,xsl,zip} \
    composer postgresql redis-server dehydrated

Set up Apache

Enable the required Apache configurations and modules:

a2enconf php7.4-fpm
a2enmod dir env headers http2 mpm_event proxy_fcgi rewrite setenvif ssl
systemctl restart apache2

You should now be able to define your virtual hosts in /etc/apache2/sites-available and enable them, with PHP support.

Deny access to git repositories

Add a global config to deny access to git repositories and other hidden stuff, in /etc/apache2/conf-available/deny-git.conf:

# /etc/apache2/conf-available/deny-git.conf
<LocationMatch "/\.(git|hg|bzr|svn|cvs|tag|ht)">
  # Old apache:
  # Order deny,allow
  # deny from all
  Require all denied
</LocationMatch>

Then enable it with:

a2enconf deny-git
systemctl reload apache2

Add a virtual host

A virtual host for a typical PHP web application should look something like this:

<VirtualHost *:443>
  ServerName app.example.com
  DocumentRoot /var/www/app

  <Directory "/var/www/app">
    Options FollowSymLinks MultiViews
    AllowOverride All
    Require all granted
  </Directory>

  SSLEngine On
  SSLCertificateFile ...
</VirtualHost>

See the Letsencrypt page for how to sort out your SSL certificates on pet servers.

Configure PHP

The configuration for PHP code hosted by Apache using PHP-FPM is located under /etc/php/7.4/fpm.

You will not be able to use mod-php php_value directives in Apache configuration; either try and do without, or set environment variables instead.

PHP works a lot better with a few extra things configured. Enable the opcache, increase the memory limit, and depending on what you're hosting, increase the maximum POST size so users can upload photos and other large files. Other fun helpful things include using Redis for PHP sessions, and tuning the FPM process parameters to make stuff more efficient under load.

Keep your PHP custom settings and tweaks separate

Since Debian now moves files around with each new version of PHP, you can keep your customisations to the php.ini file in a local configuration. For example, instead of editing /etc/php/7.4/fpm/php.ini, put these settings in /etc/php/local/php.ini:

; /etc/php/local/php.ini
; Override settings in the dist php.ini here
; make a symbolic link to this file in /etc/php/<version>/fpm/conf.d/99-local.ini
max_execution_time = 60
memory_limit = 512M
post_max_size = 500M
upload_max_filesize = 500M
opcache.enable=1

Then we add a symbolic link in the conf.d directory where you need it, for example:

ln -s /etc/php/local/php.ini /etc/php/7.4/fpm/conf.d/99-local.ini