= PHP-FPM = The PHP '''FastCGI Process Manager''' ('''PHP-FPM''') is an implementation of the [[Protocols/CGI|FastCGI]] specification. <> ---- == Installation == `php-fpm(8)` naturally depends on `php(1)`. See [[PHP#Installation|here]] for help with installation, and [[PHP/Configuration|here]] for help with configuration. Most [[Linux]] and [[BSD]] distributions will offer a `php-fpm` package. Official container images are available from the upstream development team. They are tagged like `php:-fpm` ---- == Configuration == `php-fpm(8)` listens on one or more ports or sockets. Each point of contact is a '''pool'''. Each pool should have it's own configuration file under `/etc/php/php.fpm.d`. A pool's name (`$pool`) is derived from the section header. As an example: {{{ [www] user = www-data group = www-data listen = 9000 listen.allowed_clients = 127.0.0.1, 192.168.86.1 pm = dynamic pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3 }}} === TCP Sockets === The above example uses a shorthand: `listen = 9000`. This causes `php-fpm(8)` to listen on all addresses at port 9000. However, `listen.allowed_clients` overrides this with a client whitelist. This should be comma-separated. An IPv4 address is specified like `127.0.0.1:9000`; an IPv6 address is specified like `[::1]:9000`. === Unix Sockets === To use a [[Linux/Networking#Unix_Sockets|Unix socket]] to pass requests, try: {{{ listen = /run/php-fpm/php-fpm.sock listen.owner = www-data listen.group = www-data listen.mode = 0660 }}} === Static Process Management === A pool spawns and maintains `pm.max_children` number of processes. {{{ pm = static pm.max_children = 5 }}} === Dynamic Process Management === A pool spawns `pm.start_servers` processes. At any given time, some number are 'idle'. The pool tries to keep this number within the range of `pm.min_spare_servers` to `pm.max_spare_servers`, never surpassing `pm.max_children`. {{{ pm = dynamic pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3 }}} === On-Demand Process Management === A pool spawns processes on-demand up until `pm.max_children`. A process is killed after `pm.process_idle_timeout` has passed. {{{ pm = ondemand pm.max_children = 5 pm.process_idle_timeout = 10s }}} === Process Termination === `php(1)` scripts are known to leak memory frequently. As such, a regular task is to terminate long-running processes. A simple solution is to set `pm.max_requests` to any number other than 0. Processes are killed after handling this number of requests. === Hardening === As a security measure, the allowable script extensions should be set as strictly as possible. {{{ security.limit_extensions = .php .html .htm }}} A pool can be hardened by isolating it to a distinct working directory, or even a chroot. {{{ chroot = /absolute/path/to/chroot # or chdir = relative/or/absolute/path/to/working/directory }}} By default, `php-fpm(8)` clears all environment variables. This can be disabled, but a better strategy is to set specific environment variables. {{{ env[HOSTNAME] = $HOSTNAME env[TMP] = /tmp }}} The same is true of PHP system variables. {{{ php_admin_value[error_log] = /var/log/php-fpm.log }}} ---- == Usage == === Nginx === See [[Nginx/FastCGI#PHP-FPM|here]] for details. === Apache === See [[Apache/FastCGI#PHP-FPM|here]] for details. === Containers === When containerizing a `php(1)` service, the web server should be kept separate. See other articles for help in configuring the web server containers. A template container image recipe looks like: {{{ FROM php:fpm-alpine RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" COPY myapp/ /myapp/ COPY confs/ /usr/local/etc/php-fpm.d/ EXPOSE 9000 WORKDIR /myapp CMD php-fpm --nodaemonize }}} By default, `php-fpm(8)` will not run as root. The `--allow-to-run-as-root` flag may need to be added. ---- == See also == [[https://man.archlinux.org/man/php-fpm.8|php-fpm(8)]] ---- CategoryRicottone