Qué es PHP-FPM | Instalar y configurar PHP-FPM

Entorno de prueba Familia RHELAlmaLinux 9.8Apache 2.4 + PHP-FPM 8.3Cuenta rootVerificado el 2026-10-26

PHP-FPM es un administrador de procesos FastCGI en el que unos procesos worker, iniciados de antemano, reciben las solicitudes PHP que les pasa un servidor web y las atienden. En un servidor AlmaLinux 9 con Apache, esta guía comprueba si está instalado y cómo se configuran los pools y los sockets de cada sitio, y llega hasta la prueba de la configuración y la comprobación del estado con la salida real.

Apache también puede ejecutar PHP directamente con mod_php, pero si se lo pasa a PHP-FPM, el servidor web y PHP quedan separados. Nginx no puede ejecutar PHP directamente, así que pasa las solicitudes a un proceso FastCGI como PHP-FPM. Por eso un solo PHP-FPM se puede conectar tanto con Apache como con Nginx. La configuración de pools y la estructura de sockets que se ven más abajo se aplican tal cual cuando conectas PHP-FPM con Nginx.

1️⃣ Qué es PHP-FPM: la diferencia entre CGI y FastCGI

CGI (Common Gateway Interface) es la forma estándar en que un servidor web ejecuta un programa externo para generar contenido dinámico, y inicia el programa de nuevo cada vez que llega una solicitud. El coste de crear y eliminar un proceso por solicitud se acumula, así que el servidor responde más lento a medida que aumentan las visitas.

FastCGI evita ese coste iniciando el programa de antemano y atendiendo las solicitudes una tras otra. Es la diferencia entre encender y apagar el ordenador cada vez que lo usas y usar directamente un ordenador que ya está encendido. PHP-FPM (FastCGI Process Manager) es el administrador que ejecuta PHP mediante FastCGI, y viene incluido en PHP desde la versión 5.3.3.

En cada pool, que es un grupo de workers, PHP-FPM inicia de antemano el número de workers que se haya fijado; un worker libre recibe la solicitud que el servidor web le pasa por el socket, la atiende y espera la siguiente. Los archivos estáticos, como imágenes y CSS, los responde directamente el servidor web, y solo los archivos PHP pasan a PHP-FPM. Lo único que cambia es cómo el servidor web pasa las solicitudes al socket: Apache usa el módulo mod_proxy_fcgi y Nginx usa la directiva fastcgi_pass.

🧩 Cómo atienden las solicitudes CGI y PHP-FPM
Diagrama explicativo
⚙️ Ejecución de PHP
🌐 Servidor web
🌐 ApacheNginx
📨 Solicitud 1 · index.php📨 Solicitud 2 · wp-login.php📨 Solicitud 3 · index.php
Los archivos estáticos (imágenes, CSS) los responde directamente el servidor web
Se ejecuta en cada solicitudFastCGI · socket→
🧱 Procesos CGI
Solicitud 1Proceso nuevo → atiende → termina
Solicitud 2Proceso nuevo → atiende → termina
Solicitud 3Proceso nuevo → atiende → termina
Al terminar de atender, el proceso desaparece · la siguiente solicitud empieza de nuevo
🧰 Pool de PHP-FPM [siteuser]
Worker 1Solicitud 1
Worker 2Solicitud 2
Worker 3Solicitud 3
Worker 4espera
Worker 5espera
Los workers iniciados de antemano reciben las solicitudes y, al terminar, esperan la siguiente
Si Apache ejecuta PHP como CGI, inicia un proceso PHP nuevo en cada solicitud y lo termina al acabar de atenderla, así que el coste de crear procesos se acumula a medida que aumentan las solicitudes.
Nginx no tiene ningún módulo que ejecute programas CGI directamente, por lo que esta combinación no se usa; PHP se pasa a PHP-FPM mediante FastCGI.
Apache pasa las solicitudes de PHP al socket con mod_proxy_fcgi, y un worker de PHP-FPM iniciado de antemano la recibe, la atiende y espera la siguiente.
Nginx las pasa al mismo socket con fastcgi_pass, así que aunque el servidor web sea otro, el pool de PHP-FPM sigue siendo el mismo.

2️⃣ Instalar PHP-FPM: comprobar el paquete e instalar con dnf

Si instalaste PHP con dnf en un servidor de la familia RHEL, el paquete php-fpm se instaló junto con él. Primero comprueba con rpm si está instalado. El proceso de instalación de PHP es el mismo que en Instalar APM en Rocky Linux.

rpm -qa | grep php-fpm
php-fpm-8.3.36-1.module_php.8.3.el9.remi.x86_64

Si la salida está vacía, no está instalado; instálalo con dnf.

dnf -y install php-fpm

Cuando termine la instalación, vuelve a ejecutar el mismo comando rpm para comprobar que se muestra el nombre del paquete.

3️⃣ Configurar PHP-FPM: el pool www.conf, el socket y los modos estático y dinámico

Hay dos archivos de configuración: la configuración general [/etc/php-fpm.conf] y la configuración de pools [/etc/php-fpm.d/www.conf]. Las líneas que conviene mirar primero en el pool predeterminado www.conf son listen y pm, y los valores justo después de la instalación son estos.

grep -E '^(listen|pm) ' /etc/php-fpm.d/www.conf
listen = /run/php-fpm/www.sock
pm = dynamic

listen es el lugar al que el servidor web pasa las solicitudes, y el valor predeterminado en la versión 8.3 es el socket Unix [/run/php-fpm/www.sock]. El valor predeterminado de las versiones antiguas, [127.0.0.1:9000], recibe las solicitudes por un puerto TCP. Dentro del mismo servidor, el socket es más ligero porque se ahorra el proceso de conexión por puerto, y con listen.owner y listen.group puedes restringir el acceso como si fueran permisos de archivo.

🔲 Configurar el modo estático y el modo dinámico

pm es la forma de iniciar los workers, y se fija en uno de estos tres valores: static, dynamic u ondemand. El modo estático mantiene siempre iniciado el número que pongas en pm.max_children, y la configuración de abajo mantiene 100 workers.

pm = static
pm.max_children = 100

El modo dinámico es el predeterminado y sube o baja el número de workers según el volumen de solicitudes. La configuración de abajo inicia 12 al arrancar, mantiene entre 6 y 18 workers libres y crece hasta un máximo de 120.

pm = dynamic
pm.max_children = 120
pm.start_servers = 12
pm.min_spare_servers = 6
pm.max_spare_servers = 18

El modo ondemand inicia workers solo cuando llega una solicitud y los termina cuando pasa pm.process_idle_timeout, así que va bien para sitios con pocas visitas y no para sitios con muchas.

Los tres modos se diferencian en cuándo inician los workers y en cómo suben o bajan su número.

ModoCómo se inician los workersSitios adecuados
static (estático)Mantiene siempre iniciado el número indicado en pm.max_childrenSitios con muchas visitas
dynamic (dinámico)Predeterminado · sube o baja dentro de pm.start_servers, pm.min_spare_servers y pm.max_spare_servers según el volumen de solicitudesSitios cuyas visitas suben y bajan
ondemandLos inicia solo cuando llega una solicitud y los termina cuando pasa pm.process_idle_timeoutSitios con pocas visitas

max_children se fija dividiendo la memoria del servidor entre la memoria que usa un worker. Aunque se acumulen avisos de que se ha alcanzado [max_children], no lo subas enseguida; primero averigua en los logs qué solicitudes llenaron los workers.

La memoria y el límite de subida se fijan en php.ini, la configuración general de PHP, y se ajustan junto con el número de workers según el sitio que administres.

memory_limit = 1024M
post_max_size = 128M
upload_max_filesize = 128M

Los tres valores son el límite de memoria que puede usar un script PHP y el tamaño de los archivos que se pueden subir de una vez, y solo se aplican después de reiniciar PHP-FPM.

🔲 Configurar un pool por cuenta de sitio

Si hay varios sitios, no compartas un único www.conf: crea un archivo de pool por cuenta y separa la cuenta de ejecución y el socket. El PHP de un sitio no puede leer los archivos de otra cuenta, y el número de workers se fija para cada sitio.

vi /etc/php-fpm.d/siteuser.conf

En el archivo se escriben el nombre del pool, la cuenta de ejecución, la ruta del socket y el número de workers.

[siteuser]
user = siteuser
group = nobody
listen = /run/php-fpm/siteuser.sock
listen.owner = siteuser
listen.group = nobody
listen.mode = 0660
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
chdir = /home/siteuser/www

listen.owner y listen.group son el propietario y el grupo del archivo del socket, y PHP-FPM crea el socket con estos valores al arrancar. Si el servidor web se ejecuta con la cuenta nobody, escribe nobody en listen.group; si usa la cuenta apache, escribe apache, para que el servidor web pueda abrir el socket.

listen.owner = siteuser
listen.group = nobody
listen.mode = 0660

Estas tres líneas van en cada archivo de pool, y después de cambiar los valores hay que reiniciar para que el socket se vuelva a crear con los permisos nuevos.

🔲 Configurar slowlog

slowlog es un archivo que registra en qué punto se estaba ejecutando una solicitud que tardó más que request_slowlog_timeout, y con un valor de 0 no registra nada. Cuando busques la causa de las solicitudes lentas, actívalo indicando los segundos, por ejemplo 3s.

slowlog = /var/log/php-fpm/www-slow.log
request_slowlog_timeout = 0

El archivo registrado conserva la ruta del script de la solicitud lenta y la función que se estaba ejecutando en ese momento, así que puedes ver qué plugin o qué código tardó más.

4️⃣ Integración con Apache: configuración de VirtualHost y permisos del socket

Apache pasa las solicitudes de archivos PHP al socket del pool con el módulo mod_proxy_fcgi. Pones una línea SetHandler dentro de FilesMatch en el VirtualHost, y en cada sitio escribes el socket de su cuenta.

# Un VirtualHost por cuenta de sitio · en SetHandler va el socket de esa cuenta (en lugar de SetHandler también se puede conectar con ProxyPassMatch)
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /home/siteuser/www

    <Directory /home/siteuser/www>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php-fpm/siteuser.sock|fcgi://localhost"
    </FilesMatch>
</VirtualHost>

DocumentRoot y Directory son la raíz web de esa cuenta, y -Indexes en Options evita que el listado de carpetas se muestre en el navegador.

🔲 Configurar los permisos del socket

Al iniciar el pool se crea el socket con los valores de listen.owner, listen.group y listen.mode, y con ls compruebas que los permisos son correctos.

ls -l /run/php-fpm/
total 4
srw-rw----  1 siteuser_a nobody 0 oct 22 23:34 siteuser_a.sock
-rw-r--r--  1 root       root   7 oct 26 03:00 php-fpm.pid
srw-rw----  1 siteuser_b nobody 0 oct 22 23:34 siteuser_b.sock
srw-rw----+ 1 root       root   0 oct 22 23:34 www.sock

Si los permisos no coinciden y el servidor web no puede abrir el socket, los visitantes reciben un error 503; para corregirlo enseguida sin reiniciar, indica el propietario y los permisos con chown y chmod.

Esta es la sintaxis actual, que separa el usuario y el grupo con dos puntos.

chown siteuser:nobody /run/php-fpm/siteuser.sock

Después de cambiar el propietario, ajusta los permisos a 660.

chmod 660 /run/php-fpm/siteuser.sock

Esta es la sintaxis antigua, que separa el usuario y el grupo con un punto, y chown la sigue ejecutando tal cual en AlmaLinux 9.

chown siteuser.nobody /run/php-fpm/siteuser.sock

Después de cambiar el propietario, ajusta los permisos a 660.

chmod 660 /run/php-fpm/siteuser.sock

El resultado de las dos sintaxis es el mismo: uses la que uses, el propietario del socket pasa a ser siteuser y el grupo pasa a ser nobody.

🔲 Integración con Nginx: la directiva fastcgi_pass

En Nginx, el location de los archivos PHP dentro del bloque server pasa las solicitudes al socket del mismo pool con fastcgi_pass.

location ~ \.php$ {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass unix:/run/php-fpm/siteuser.sock;
}

Si Nginx se ejecuta con la cuenta nginx, hay que escribir nginx en listen.group del archivo de pool para que pueda abrir el socket.

5️⃣ Prueba de la configuración y reinicio: php-fpm -t y systemctl

Después de cambiar la configuración, no reinicies enseguida; haz primero una comprobación de sintaxis con php-fpm -t. Si hay una errata en un archivo de pool, al reiniciar se cae todo PHP-FPM y todos los sitios reciben un 503.

php-fpm -t
[26-Oct-2026 17:33:45] NOTICE: configuration file /etc/php-fpm.conf test is successful

Si la comprobación se supera, se muestra el mensaje [test is successful] junto con la ruta del archivo de configuración, y después aplicas el cambio en PHP-FPM. Los cambios que obligan a volver a crear el socket, como la ruta del socket o listen.owner, se aplican con restart. Si en un servidor en producción solo cambiaste valores como el número de workers, aplícalo con reload.

systemctl restart php-fpm

Si editaste el VirtualHost, reinicia también Apache.

systemctl restart httpd

Regístralo con enable para que se ejecute automáticamente cuando el servidor se vuelva a encender.

systemctl enable php-fpm

Comprueba si está registrado con is-enabled.

systemctl is-enabled php-fpm
enabled

Con status comprueba que hay workers en marcha en cada pool.

systemctl status php-fpm
● php-fpm.service - The PHP FastCGI Process Manager
     Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; enabled; preset: disabled)
     Active: active (running) since x
    Process: 3934033 ExecReload=/bin/kill -USR2 $MAINPID (code=exited, status=0/SUCCESS)
   Main PID: 1333314 (php-fpm)
     Status: "Processes active: 4, idle: 21, Requests: x, slow: 0, Traffic: x"
      Tasks: x
     Memory: x
        CPU: x
     CGroup: /system.slice/php-fpm.service
             ├─  41920 "php-fpm: pool siteuser_a"
             ├─  94143 "php-fpm: pool siteuser_b"
             ├─1333314 "php-fpm: master process (/etc/php-fpm.conf)"
             ├─3934078 "php-fpm: pool www"
             └─4009016 "php-fpm: pool siteuser_a"

oct 26 03:00:01 server.example.com systemd[1]: Reloading The PHP FastCGI Process Manager...
oct 26 03:00:01 server.example.com systemd[1]: Reloaded The PHP FastCGI Process Manager.

En la línea Status, active e idle son los workers que están atendiendo solicitudes ahora mismo y los que están libres, y CGroup enumera los workers por nombre de pool. El nombre del host y los nombres de los pools de la salida se han sustituido por valores de ejemplo.

🔢 FAQ & contenido recomendado

mod_php ejecuta PHP dentro del proceso de Apache, así que la configuración es sencilla, pero PHP se carga en cada worker de Apache, lo que gasta mucha memoria y dificulta separar la cuenta de ejecución por sitio. PHP-FPM separa PHP en procesos aparte, de modo que cada sitio puede tener su propia cuenta y su propio número de workers; por eso, en un servidor con varios sitios o que usa Nginx, se usa PHP-FPM.

systemctl reload php-fpm envía una señal USR2 al proceso maestro, que vuelve a leer la configuración y sustituye los workers. Si fijas process_control_timeout, se sustituyen primero los workers que han terminado la solicitud que estaban atendiendo (según la documentación oficial). restart baja todos los workers y los vuelve a subir de una vez, así que las solicitudes de ese momento pueden cortarse; en un servidor en producción, usa primero reload.

En la familia RHEL, el log predeterminado es [/var/log/php-fpm/error.log], y ahí quedan los avisos de falta de workers (seems busy · max_children) y los registros de inicio y parada de los pools. En el archivo que indiques en cada pool con php_admin_value[error_log] se registran aparte los errores del código PHP de ese sitio. El pool predeterminado registra en [/var/log/php-fpm/www-error.log].

ℹ️ Aviso de afiliados
El contenido de este sitio incluye enlaces de afiliado. Cuando un visitante compra un producto o servicio a través de uno de ellos, el sitio recibe una comisión del vendedor. El importe que paga el comprador(baja durante las promociones ↓)no aumenta. Los precios, descuentos y existencias publicados corresponden al momento de redacción y pueden variar, así que confírmalos con el vendedor antes de comprar. Los productos se eligen y evalúan con criterios propios, y las comisiones no influyen en el orden ni en el contenido de las reseñas.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Demuestra que eres humano: 2   +   4   =