Exponer métricas PHP‑FPM para Prometheus con exporter en Docker Compose (tutorial)
Docker & Containers · Por Kevin Marcondes · Publicado el · 7 min de lectura
Tutorial: exponer métricas de PHP‑FPM a Prometheus usando un exporter en Docker Compose. Activarás el status de PHP‑FPM, levantarás un exporter dedicado y configurarás Prometheus para recolectar las métricas. Al final validamos con curl y desde la UI de Prometheus, además de dar consejos para múltiples pools y seguridad.
Arquitectura: cómo funciona el scraping
PHP‑FPM expone estadísticas en pm.status_path. Un exporter traduce esos datos al formato de Prometheus y los publica en /metrics. Prometheus hace el scrape de ese endpoint de forma periódica. Todo se ejecuta en contenedores separados orquestados por Docker Compose.
Esta separación facilita aislar responsabilidades, aplicar límites y evolucionar cada componente sin acoplamiento. A continuación los roles y puertos por defecto:
| Componente | Puerto | Rol |
|---|---|---|
| php-fpm | 9000/TCP | Ejecuta el pool PHP y expone /status vía FastCGI |
| php-fpm-exporter | 9253/TCP | Se conecta a /status y sirve /metrics |
| prometheus | 9090/TCP | Hace el scrape del exporter y almacena series temporales |
Prerequisitos y avisos importantes
Antes de comenzar necesitas Docker y Docker Compose instalados y acceso al terminal. Este paso a paso usa imágenes oficiales y configuraciones mínimas pensadas para desarrollo o laboratorio.
- Atención: el status de PHP‑FPM no tiene autenticación. Mantén el acceso restringido a la red interna de Docker o localhost. No publiques /status en Internet.
- Atención: mapear puertos públicos expone servicios. Prefiere enlazar a 127.0.0.1 durante las pruebas.
- Docker y Docker Compose instalados
- Permisos para ejecutar docker compose
- Puertos 9090 y 9253 libres en la máquina local (o ajusta)
- Conocimientos básicos de YAML y Linux
Estructura de carpetas del proyecto
Crearemos dos carpetas para separar la configuración de PHP‑FPM y Prometheus. Los archivos se irán rellenando en las secciones siguientes.
Estructura sugerida:
- - php-fpm/www.conf
- - prometheus/prometheus.yml
- - docker-compose.yml
mkdir -p php-fpm prometheus
ls -la
# Depois, criaremos os arquivos nas seções seguintes com o conteúdo correto.
Habilitar el status de PHP‑FPM (pm.status_path)
El exporter depende del endpoint de status de PHP‑FPM. Activa pm.status_path y asegúrate de que PHP‑FPM escuche en TCP (puerto 9000) para facilitar la comunicación entre contenedores.
Guarda el archivo siguiente como php-fpm/www.conf.
[www]
user = www-data
group = www-data
; Ouça em TCP para facilitar a conexão do exporter
listen = 9000
; Gerenciador de processos
pm = dynamic
pm.max_children = 20
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 4
; Endpoints internos do FPM
pm.status_path = /status
ping.path = /ping
; Logs para stdout/stderr do container
access.log = /proc/self/fd/2
clear_env = no
Docker Compose: php-fpm y php-fpm-exporter
Ahora orquestaremos PHP‑FPM y el exporter. El exporter hipages/php-fpm_exporter se conecta a /status vía FastCGI y sirve métricas HTTP en el puerto 9253.
Observación: el mapeo de puertos puede cambiarse a 127.0.0.1:PUERTO si quieres restringir el acceso solo al host local.
version: "3.8"
services:
php-fpm:
image: php:8.2-fpm-alpine
container_name: php-fpm
volumes:
- ./php-fpm/www.conf:/usr/local/etc/php-fpm.d/www.conf:ro
expose:
- "9000"
php-fpm-exporter:
image: hipages/php-fpm_exporter:latest
container_name: php-fpm-exporter
command:
- --phpfpm.scrape-uri=tcp://php-fpm:9000/status
- --web.listen-address=:9253
ports:
- "9253:9253" # use 127.0.0.1:9253 para restringir ao host local
depends_on:
- php-fpm
Prometheus: scrape del exporter
Con el exporter sirviendo /metrics, configura Prometheus para recolectar periódicamente. Usaremos un job dedicado con target apuntando al servicio exporter en Compose.
Guarda el archivo siguiente como prometheus/prometheus.yml y añade el servicio prometheus al Compose.
global:
scrape_interval: 15s
scrape_configs:
- job_name: "phpfpm"
static_configs:
- targets: ["php-fpm-exporter:9253"]
labels:
instance: "app-php-fpm"
Levantar los contenedores y validar las métricas
Es hora de levantar todo y comprobar. Añade/actualiza docker-compose.yml con Prometheus, inicia los servicios y verifica que /metrics devuelve datos. También revisa los targets en la UI de Prometheus.
Consejo: si quieres dashboards, consulta cómo configurar Prometheus y Grafana en Docker Compose en cómo configurar Prometheus y Grafana.
# Acrescente o serviço Prometheus no docker-compose (separado ou no mesmo arquivo)
cat >> docker-compose.yml <<'EOF'
prometheus:
image: prom/prometheus:latest
container_name: prometheus
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
ports:
- "9090:9090" # use 127.0.0.1:9090 para restringir ao host local
depends_on:
- php-fpm-exporter
EOF
# Subir o ambiente
docker compose up -d
# Verificar containers
docker compose ps
# Validar métricas do exporter
curl -s http://localhost:9253/metrics | head -n 20
# Conferir algumas séries esperadas
curl -s http://localhost:9253/metrics | grep -E 'phpfpm_(up|listen_queue|processes)'
# UI do Prometheus (navegador): http://localhost:9090/targets
# Status deve aparecer como UP para o job "phpfpm".
Buenas prácticas, múltiples pools y próximos pasos
Para cada instancia/pool de PHP‑FPM, lo más simple es ejecutar un exporter por target y añadir todos en Prometheus (varios targets en el mismo job). Evita exponer /status públicamente: mantén la comunicación restringida a la red interna de Docker.
Algunas recomendaciones prácticas:
- Restringe puertos: mapea a 127.0.0.1:9253 y 127.0.0.1:9090 cuando sea posible.
- Mantén pm.status_path habilitado solo donde el exporter lo necesite. En producción, no lo publiques vía HTTP externo.
- Usa labels coherentes (instance, service, env) en Prometheus para facilitar dashboards.
- Crea alertas para cola de listen alta y procesos ocupados persistentes.
- Optimiza pm.* del FPM según la carga; las métricas ayudan a validar el tuning. Ver: fuga de memoria en PHP‑FPM (/es/fuga-memoria-php-fpm).
- Para visualización, conecta Prometheus a Grafana. Compara stacks en /es/comparativa-prometheus-grafana-vs-loki-tempo-php y complementa con logs centralizados (Fluentd + Elasticsearch: /es/fluentd-elasticsearch-logs-php-vps).
Errores comunes y cómo diagnosticar rápidamente
Algunos problemas aparecen con frecuencia durante la configuración inicial. Revisa las causas típicas y correcciones directas a continuación.
- Conexión rechazada en el exporter: confirma que php-fpm está escuchando en 9000 y el nombre del servicio (tcp://php-fpm:9000/status).
- 404 en /status: verifica pm.status_path en www.conf y reinicia el FPM (recrea el contenedor).
- Exporter UP pero métricas vacías: revisa permisos y que el pool activo sea [www].
- Target DOWN en Prometheus: prueba curl desde el host de Prometheus; si funciona enlazando a 127.0.0.1, ajusta la red/ports.
- Listen_queue alta y persistente: indica saturación; ajusta pm.max_children e investiga cuellos de botella de CPU/IO.
Preguntas frecuentes
¿Puedo usar socket UNIX en lugar de TCP para PHP‑FPM?
Sí. El exporter puede comunicarse por FastCGI vía socket. Apunta --phpfpm.scrape-uri al path del socket, por ejemplo unix:///usr/local/var/run/php-fpm.sock, y monta el socket en el contenedor del exporter. En Compose, usa volúmenes compartidos entre php-fpm y el exporter.
¿Es seguro exponer /metrics del exporter en Internet?
Evítalo. Expón /metrics solo internamente (red de Docker o 127.0.0.1) y deja que Prometheus recolecte localmente. Si necesitas acceso remoto, añade autenticación y restricciones de IP en un proxy delante del exporter o accede vía VPN.
¿Cómo monitorizar varios pools o servicios PHP‑FPM?
Ejecuta un exporter por instancia/pool y añádelos como targets en Prometheus dentro del mismo job. También puedes crear varios jobs por entorno (p. ej. staging y producción) y usar labels para filtrar en dashboards y alertas.
¿Necesito Nginx para habilitar el status de PHP‑FPM?
No. El exporter habla FastCGI directamente con PHP‑FPM. Basta con habilitar pm.status_path y asegurarte de que FPM esté escuchando (TCP o socket). Nginx solo es útil si quieres exponer el status vía HTTP para humanos, lo cual no es necesario para Prometheus.
¿Qué métricas de PHP‑FPM son más útiles para alertas?
La cola de listen (phpfpm_listen_queue), procesos ocupados/ociosos (phpfpm_processes por estado), alcanzar la capacidad máxima y el up del target. Combínalas con latencia de la app y errores 5xx en tu proxy para tener contexto completo.
¿Quieres revisar tu stack de observabilidad en Docker?
Si necesitas configurar exporters de forma segura y estandarizada, o crear dashboards y alertas útiles para tu equipo, hablemos.
Hablar sobre observabilidad en DockerVer también
- Tutorial: implementar Canary releases con Traefik en Docker Compose usando headers y weighted routing para despliegues graduales de aplicaciones PHP
- Tutorial: configurar HAProxy con Let's Encrypt y healthchecks para balanceo de tráfico entre contenedores Docker en VPS (paso a paso)
- Tutorial práctico: implementar mTLS entre Nginx y microservicios usando smallstep CA en Docker Compose
- Tutorial: configurar cgroup v2 y systemd ResourceControl para limitar CPU, memoria e I/O de contenedores Docker en Debian