Expor métricas PHP‑FPM para Prometheus com exporter em Docker Compose (tutorial)
Docker & Containers · Por Kevin Marcondes · Publicado em · 7 min de leitura
Tutorial: expor métricas PHP‑FPM para Prometheus usando exporter em Docker Compose. Você vai habilitar o status do PHP‑FPM, subir um exporter dedicado e configurar o Prometheus para coletar as métricas. No fim, validamos com curl e na UI do Prometheus, além de dicas para múltiplos pools e segurança.
Arquitetura: como o scraping funciona
O PHP‑FPM expõe estatísticas no pm.status_path. Um exporter traduz esses dados para o formato do Prometheus e publica em /metrics. O Prometheus, então, faz o scrape desse endpoint periodicamente. Tudo roda em containers separados via Docker Compose.
Essa separação facilita isolar responsabilidades, aplicar limites e evoluir cada componente sem acoplamento. Veja os papéis e portas padrão:
| Componente | Porta | Papel |
|---|---|---|
| php-fpm | 9000/TCP | Executa o pool PHP e expõe /status via FastCGI |
| php-fpm-exporter | 9253/TCP | Conecta no /status e serve /metrics |
| prometheus | 9090/TCP | Faz o scrape do exporter e armazena séries temporais |
Pré-requisitos e avisos importantes
Antes de começar, você precisa de Docker e Docker Compose instalados e acesso ao terminal. Este passo a passo usa imagens oficiais e configurações mínimas para funcionar em desenvolvimento ou laboratório.
- Atenção: o status do PHP‑FPM não tem autenticação. Mantenha o acesso restrito à rede interna do Docker ou localhost. Não publique /status na internet.
- Atenção: mapear portas públicas expõe serviços. Prefira binding em 127.0.0.1 durante testes.
- Docker e Docker Compose instalados
- Permissão para rodar docker compose
- Portas 9090 e 9253 livres na máquina local (ou ajuste)
- Conhecimento básico de YAML e Linux
Estrutura de pastas do projeto
Criaremos duas pastas para separar a configuração do PHP‑FPM e do Prometheus. Os arquivos serão preenchidos nas próximas seções.
Estrutura 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 o status do PHP‑FPM (pm.status_path)
O exporter depende do endpoint de status do PHP‑FPM. Ative o pm.status_path e garanta que o PHP‑FPM escute em TCP (porta 9000) para facilitar a comunicação entre containers.
Salve o arquivo abaixo 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 e php-fpm-exporter
Agora vamos orquestrar o PHP‑FPM e o exporter. O exporter hipages/php-fpm_exporter conecta no /status via FastCGI e serve métricas HTTP na porta 9253.
Observação: o binding das portas pode ser alterado para 127.0.0.1:PORTA se você quiser restringir o acesso apenas ao 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 do exporter
Com o exporter servindo /metrics, configure o Prometheus para coletar periodicamente. Usaremos um job dedicado com target apontando para o serviço do exporter no Compose.
Salve o arquivo abaixo como prometheus/prometheus.yml e adicione o serviço prometheus ao Compose.
global:
scrape_interval: 15s
scrape_configs:
- job_name: "phpfpm"
static_configs:
- targets: ["php-fpm-exporter:9253"]
labels:
instance: "app-php-fpm"
Subir os containers e validar as métricas
Hora de subir tudo e conferir. Vamos criar/atualizar o docker-compose.yml com o Prometheus, iniciar os serviços e verificar se o /metrics retorna dados. Também vale checar os targets na UI do Prometheus.
Dica: se quiser dashboards, veja o guia de Prometheus+Grafana em Docker Compose em como configurar Prometheus e 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".
Boas práticas, múltiplos pools e próximos passos
Para cada instância/pool de PHP‑FPM, o padrão mais simples é executar um exporter por target e adicionar todos no Prometheus (vários targets no mesmo job). Evite expor /status publicamente: deixe a comunicação restrita à rede interna do Docker.
Algumas recomendações práticas:
- Restrinja ports: mapeie para 127.0.0.1:9253 e 127.0.0.1:9090 quando possível.
- Mantenha pm.status_path habilitado só onde o exporter acessa. Em produção, não publique via HTTP externo.
- Use labels coerentes (instance, service, env) no Prometheus para facilitar dashboards.
- Crie alertas para fila de listen alta e processos ocupados persistentes.
- Otimize pm.* do FPM conforme carga; métricas ajudam a validar tuning. Veja vazamento de memória no PHP‑FPM.
- Para visualizar, conecte o Prometheus ao Grafana. Compare stacks em Prometheus+Grafana vs Loki+Tempo e complemente com logs centralizados (Fluentd + Elasticsearch).
Erros comuns e como diagnosticar rapidamente
Alguns problemas aparecem com frequência durante a configuração inicial. Confira as causas típicas e correções diretas a seguir.
- Conexão recusada no exporter: confirme se o php-fpm está ouvindo em 9000 e o nome do serviço (tcp://php-fpm:9000/status).
- 404 no /status: verifique pm.status_path no www.conf e reinicie o FPM (recrie o container).
- Exporter UP, mas métricas vazias: confira permissões e se o pool ativo é o [www].
- Target DOWN no Prometheus: teste curl no host do Prometheus; se resolver com 127.0.0.1 binding, ajuste a rede/ports.
- Alto listen_queue constante: é sinal de saturação; ajuste pm.max_children e investigue gargalos de CPU/IO.
Perguntas frequentes
Posso usar socket UNIX em vez de TCP para o PHP‑FPM?
Sim. O exporter consegue falar FastCGI via socket. Aponte --phpfpm.scrape-uri para o caminho do socket, por exemplo unix:///usr/local/var/run/php-fpm.sock, e monte o socket no container do exporter. Em Compose, use volumes compartilhados entre php-fpm e o exporter.
É seguro expor o /metrics do exporter na internet?
Evite. Exponha o /metrics somente internamente (rede do Docker ou 127.0.0.1) e deixe o Prometheus coletar localmente. Se precisar acesso remoto, coloque autenticação e restrições de IP em um proxy na frente do exporter ou acesse via VPN.
Como monitorar vários pools ou serviços PHP‑FPM?
Execute um exporter por instância/pool e adicione todos como targets no Prometheus no mesmo job. Você também pode rodar múltiplos jobs por ambiente (ex.: staging e produção) e usar labels para filtrar em dashboards e alertas.
Preciso do Nginx para habilitar o status do PHP‑FPM?
Não. O exporter fala FastCGI diretamente com o PHP‑FPM. Basta habilitar pm.status_path e garantir que o FPM esteja escutando (TCP ou socket). Nginx é útil apenas se você quiser expor o status via HTTP para humanos, o que não é necessário ao Prometheus.
Quais métricas do PHP‑FPM são mais úteis para alertas?
A fila de listen (phpfpm_listen_queue), processos ocupados/ociosos (phpfpm_processes por estado), capacidade máxima atingida, e o up do target. Combine com latência de app e erros 5xx em seu proxy para ter contexto mais completo.
Quer revisar sua stack de observabilidade em Docker?
Se você precisa configurar exporters de forma segura e padronizada, ou criar dashboards e alertas úteis para seu time, vamos conversar.
Falar sobre observabilidade em DockerVeja também
- tutorial: implementar Canary releases com Traefik em Docker Compose usando headers e weight routing para deploys graduais de aplicações PHP
- Tutorial: configurar HAProxy com Let's Encrypt e healthchecks para balanceamento de tráfego entre containers Docker em VPS (passo a passo)
- Tutorial prático: implementar mTLS entre Nginx e microserviços usando smallstep CA em Docker Compose
- Tutorial: configurar cgroup v2 e systemd ResourceControl para limitar CPU, memória e I/O de containers Docker no Debian