Tags: FastCGI · Nginx · Caddy · Traefik · Reverse Proxy · HTTP/3 · PHP-FPM · Performance
Por Duarte Spínola · 4 de Julho de 2026
FastCGI e Reverse Proxies: Nginx vs Caddy vs Traefik em 2026
O FastCGI tem 30 anos mas continua a ser o protocolo mais eficiente para comunicar entre web servers e aplicações backend (PHP, Python, Ruby). Os reverse proxies modernos — Nginx, Caddy e Traefik — usam diferentes abordagens para terminar TLS, encaminhar tráfego e servir aplicações. Este guia compara os três, com configurações práticas e benchmarks reais, inspirado na análise técnica de agwa.name.
Para complementar, consulta os artigos sobre Caddy Reverse Proxy HTTPS, Traefik Ingress Kubernetes, Cloudflare Tunnel Zero Trust e Postfix SMTP Relay.
Conteúdos
- 1. FastCGI: 30 Anos e Ainda Melhor que HTTP
- 2. O Problema do HTTP como Proxy Backend
- 3. Nginx vs Caddy vs Traefik: Comparação
- 4. Configurar Nginx com FastCGI
- 5. Configurar Caddy com PHP-FPM
- 6. Configurar Traefik com Docker
- 7. HTTP/3 e QUIC
- 8. Terminação TLS e Autocert
- 9. Benchmarks e Performance
- 10. Optimizar PHP-FPM
- 11. Cenário Prático PME
- 12. Boas Práticas
- 13. Checklist de Implementação
1. FastCGI: 30 Anos e Ainda Melhor que HTTP
O FastCGI foi introduzido em 1996 pela Open Market como evolução do CGI tradicional. Em vez de lançar um processo novo por pedido (CGI), o FastCGI mantém processos persistentes que recebem múltiplos pedidos por um socket. Trinta anos depois, continua a ser o protocolo mais eficiente para comunicar com aplicações backend.
Vantagens do FastCGI sobre HTTP como protocolo de proxy:
- Binário, não texto — cabeçalhos em pares nome/valor, sem parsing de HTTP
- Menos overhead — sem headers HTTP completos no pedido interno
- Multiplexação — múltiplos pedidos num só socket (FastCGI suporta streams)
- Sem buffering — streaming directo, sem limite de tamanho de body
- Timeouts granulares — separate read timeout, write timeout, connect timeout
💡 Dica: Quando o reverse proxy fala FastCGI directamente com a aplicação (em vez de HTTP), evita uma camada completa de parsing HTTP. Para WordPress/PHP, isto significa ~15-20% menos overhead por pedido.
2. O Problema do HTTP como Proxy Backend
Quando um reverse proxy usa HTTP para comunicar com o backend, há problemas:
- Duplicação de headers — o proxy adiciona X-Forwarded-For, X-Real-IP, Host, etc., que o backend tem de interpretar
- Buffering obrigatório — muitos proxies fazem buffer do body completo antes de encaminhar
- Timeouts confusos — o timeout HTTP do proxy não distingue connect, read, write
- Limites de tamanho — client_max_body_size, proxy_request_buffering
- Conexões TCP extras — cada pedido cria uma nova conexão TCP (ou usa keepalive pool)
Com FastCGI, o proxy e o backend partilham um socket Unix persistente. Sem overhead TCP, sem headers HTTP duplicados, sem buffering desnecessário.
3. Nginx vs Caddy vs Traefik: Comparação
| Característica | Nginx | Caddy | Traefik |
|---|---|---|---|
| Linguagem | C | Go | Go |
| FastCGI nativo | Sim (excelente) | Sim (v2.7+) | Não |
| Autocert TLS | Não (requer Certbot) | Sim (built-in) | Sim (Let’s Encrypt) |
| HTTP/3 (QUIC) | Sim (1.25+) | Sim (experimental) | Sim |
| Configuração | Arquivo .conf | Caddyfile (simples) | YAML/TOML/labels |
| Docker integration | Manual | Manual | Automática (labels) |
| Hot reload | Sim (nginx -s reload) | Sim (caddy reload) | Sim (automático) |
| Performance | Máxima (C/ASM) | Alta (Go) | Alta (Go) |
| Ideal para | Produção, alta carga, PHP | Simplicidade, autocert | Docker/Kubernetes |
4. Configurar Nginx com FastCGI
# Nginx + PHP-FPM via FastCGI (Unix socket)
# /etc/nginx/sites-available/empresa.conf
upstream php-fpm {
server unix:/run/php/php8.3-fpm.sock;
# Ou TCP: server 127.0.0.1:9000;
}
server {
listen 80;
listen 443 ssl http2;
server_name empresa.pt www.empresa.pt;
ssl_certificate /etc/letsencrypt/live/empresa.pt/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/empresa.pt/privkey.pem;
root /var/www/empresa;
index index.php index.html;
# FastCGI para PHP
location ~ \.php$ {
fastcgi_pass php-fpm;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# Timeouts FastCGI
fastcgi_connect_timeout 5s;
fastcgi_read_timeout 60s;
fastcgi_send_timeout 60s;
# Buffering (desligar para streaming)
fastcgi_buffering off;
fastcgi_request_buffering off;
# Buffers
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
}
# Proxy para backend Node.js/Python (HTTP, não FastCGI)
location /api/ {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# Fichérios estáticos
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
}
# Instalar Nginx + PHP-FPM no Ubuntu/Debian
sudo apt update
sudo apt install -y nginx php8.3-fpm php8.3-mysql php8.3-gd php8.3-curl
# Activar site
sudo ln -s /etc/nginx/sites-available/empresa.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
# Verificar PHP-FPM
sudo systemctl status php8.3-fpm
# Benchmark rápido
ab -n 1000 -c 10 https://empresa.pt/
# Com FastCGI: ~2000 req/s em hardware modesto
5. Configurar Caddy com PHP-FPM
# Caddyfile — muito mais simples que Nginx
empresa.pt {
root * /var/www/empresa
encode gzip zstd
# FastCGI para PHP-FPM
php_fastcgi unix//run/php/php8.3-fpm.sock {
# Configuração equivalente ao Nginx
# Caddy trata SCRIPT_FILENAME automaticamente
}
# Reverse proxy para API Node.js
reverse_proxy /api/* 127.0.0.1:3000
# Ficheiros estáticos
file_server
header Cache-Control "public, max-age=2592000"
# TLS automático (Caddy pede e renova certificados Let's Encrypt)
# Não precisas configurar nada — é automático
}
# Múltiplos sites
api.empresa.pt {
reverse_proxy 127.0.0.1:3000
}
blog.empresa.pt {
root * /var/www/blog
php_fastcgi unix//run/php/php8.3-fpm.sock
file_server
}
# Instalar Caddy
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install -y caddy
# Iniciar
sudo systemctl start caddy
# Caddy automaticamente:
# 1. Pede certificado Let's Encrypt
# 2. Configura TLS 1.3
# 3. Redirect HTTP -> HTTPS
# 4. Renova certificados automaticamente
# 5. Serve PHP via FastCGI
# 6. Serve ficheiros estáticos
# Hot reload após alterar Caddyfile
sudo caddy reload --config /etc/caddy/Caddyfile
6. Configurar Traefik com Docker
# docker-compose.yml com Traefik + WordPress + API Node.js
version: '3.8'
services:
traefik:
image: traefik:v3.2
command:
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --entrypoints.websecure.http3=true
- [email protected]
- --certificatesresolvers.le.acme.storage=/acme.json
- --certificatesresolvers.le.acme.tlschallenge=true
ports:
- "80:80"
- "443:443"
- "443:443/udp" # HTTP/3 QUIC
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./acme.json:/acme.json
restart: always
wordpress:
image: wordpress:php8.3-fpm-alpine
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wp
WORDPRESS_DB_PASSWORD: SubstituirPassword
volumes:
- wp-data:/var/www/html
labels:
- "traefik.enable=true"
- "traefik.http.routers.wp.rule=Host(`empresa.pt`)"
- "traefik.http.routers.wp.tls=true"
- "traefik.http.routers.wp.tls.certresolver=le"
# Traefik não fala FastCGI nativamente — usa HTTP para o WordPress
# Solução: usar Nginx como sidecar para FastCGI
- "traefik.http.services.wp.loadbalancer.server.port=9000"
# Nota: isto envia HTTP para o PHP-FPM que espera FastCGI
# Para FastCGI real, precisa de Nginx sidecar
depends_on:
- db
api:
image: node:22-alpine
command: node /app/server.js
volumes:
- ./api:/app
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`api.empresa.pt`)"
- "traefik.http.routers.api.tls=true"
- "traefik.http.routers.api.tls.certresolver=le"
- "traefik.http.services.api.loadbalancer.server.port=3000"
db:
image: mariadb:11
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wp
MYSQL_PASSWORD: SubstituirPassword
MYSQL_ROOT_PASSWORD: SubstituirRootPassword
volumes:
- db-data:/var/lib/mysql
volumes:
wp-data:
db-data:
⚠ Nota: O Traefik não suporta FastCGI nativamente. Para WordPress/PHP com Traefik, usa Nginx como sidecar (fastcgi para PHP-FPM + HTTP para Traefik). O Caddy e Nginx suportam FastCGI directamente.
7. HTTP/3 e QUIC
O HTTP/3 usa QUIC (Quick UDP Internet Connections) em vez de TCP. Reduz latência em conexões instáveis (mobile, redes com perda de pacotes).
| Característica | HTTP/2 (TCP) | HTTP/3 (QUIC) |
|---|---|---|
| Transporte | TCP | UDP |
| TLS | TLS 1.3 | Built-in (QUIC crypto) |
| Head-of-line blocking | Sim (TCP) | Não (streams independentes) |
| 0-RTT | Não | Sim (resumo de sessão) |
| Multiplexação | Sim (mas limitada pelo TCP) | Sim (real) |
# Activar HTTP/3 no Nginx (1.25+)
# Necessário compilar com --with-http_v3_module ou usar pacote que inclua
server {
listen 443 ssl;
listen 443 quic reuseport; # HTTP/3
http2 on;
http3 on;
server_name empresa.pt;
ssl_certificate /etc/letsencrypt/live/empresa.pt/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/empresa.pt/privkey.pem;
# Anunciar HTTP/3 no header Alt-Svc
add_header Alt-Svc 'h3=":443"; ma=86400';
# ... resto da configuração
}
# No Caddy, HTTP/3 é automático (experimental, pode necessitar flag)
# caddy run --config Caddyfile --experimental-http3
# No Traefik, activar http3 no entrypoint (ver docker-compose acima)
# --entrypoints.websecure.http3=true
8. Terminação TLS e Autocert
# Caddy: TLS 100% automático
# O Caddy pede, instala e renova certificados Let's Encrypt
# Sem Certbot, sem cron, sem configuração extra
# Basta ter o domínio a apontar para o servidor
# Nginx: TLS com Certbot
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d empresa.pt -d www.empresa.pt
# Renovação automática via systemd timer
sudo systemctl status certbot.timer
# Traefik: TLS automático via labels
# labels:
# - traefik.http.routers.site.tls=true
# - traefik.http.routers.site.tls.certresolver=le
# O Traefik pede e renova automaticamente
# Verificar TLS
curl -vI https://empresa.pt 2>&1 | grep -i "ssl\|tls"
# Deve mostrar: TLSv1.3
# Verificar certificado
echo | openssl s_client -connect empresa.pt:443 -servername empresa.pt 2>/dev/null | openssl x509 -noout -dates
9. Benchmarks e Performance
Benchmarks aproximados (servidor 2 vCPU, 4GB RAM, Ubuntu 24.04, PHP 8.3, WordPress default):
| Cenário | Nginx + FastCGI | Caddy + FastCGI | Traefik + HTTP |
|---|---|---|---|
| Req/s (estático) | ~12.000 | ~9.000 | ~7.000 |
| Req/s (WordPress) | ~2.200 | ~1.900 | ~1.500 |
| Latência p50 | ~5ms | ~7ms | ~9ms |
| Memória (idle) | ~20MB | ~30MB | ~50MB |
| Configuração | Complexa | Muito simples | Média (labels) |
💡 Dica: A diferença de performance entre Nginx e Caddy é ~15-20%, mas o Caddy compensa com TLS automático e configuração 10x mais simples. Para a maioria das PMEs, Caddy é a melhor escolha. Para alta carga, Nginx.
10. Optimizar PHP-FPM
# /etc/php/8.3/fpm/pool.d/www.conf
# Process manager: dynamic (ajusta workers consoante carga)
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 500 # Reinicia worker após 500 pedidos (previne memory leaks)
# Unix socket (mais rápido que TCP)
listen = /run/php/php8.3-fpm.sock
listen.owner = www-data
listen.group = www-data
# Buffer de FastCGI
listen.backlog = 65535
# Slow log (pedidos que demoram mais que X segundos)
request_slowlog_timeout = 5
slowlog = /var/log/php8.3-fpm/slow.log
# Calcular max_children:
# max_children = RAM_total / (RAM_per_worker)
# Exemplo: 4GB RAM, cada worker usa ~50MB
# max_children = 4096 / 50 = ~80
# Mas reservar RAM para OS/DB: usar 50
# Reiniciar PHP-FPM
sudo systemctl restart php8.3-fpm
# Verificar workers activos
ps aux | grep php-fpm | grep -v grep | wc -l
11. Cenário Prático PME
Para uma PME que precisa de servir WordPress + API Node.js + site estático:
| Componente | Recomendado |
|---|---|
| Reverse proxy | Caddy (simplicidade + autocert) |
| WordPress | PHP-FPM 8.3 via FastCGI (Unix socket) |
| API Node.js | reverse_proxy para 127.0.0.1:3000 |
| Cache | Redis + Caddy encode gzip/zstd |
| TLS | Caddy autocert (Let’s Encrypt) |
| Se Docker | Traefik (labels automáticos) |
12. Boas Práticas
- Usar Unix sockets para FastCGI — mais rápido que TCP (sem overhead de rede)
- Desligar buffering para APIs que fazem streaming (fastcgi_buffering off)
- Configurar slow log no PHP-FPM para detectar pedidos lentos
- Usar OPcache — cache de bytecode PHP, reduz latency ~40%
- Comprimir respostas — gzip ou zstd (Caddy suporta ambos nativamente)
- Cache de estáticos — header Cache-Control com max-age adequado
- HTTP/3 — reduzir latência em mobile e redes instáveis
- Renovar TLS — usar TLS 1.3, desactivar TLS 1.0/1.1
- Rate limiting — proteger contra DDoS básico
- Logs estruturados — JSON logs para integração com Grafana/ELK
13. Checklist de Implementação
- ☐ Escolher reverse proxy (Caddy para simplicidade, Nginx para performance, Traefik para Docker)
- ☐ Configurar FastCGI para PHP-FPM (Unix socket)
- ☐ Activar TLS automático (Caddy built-in, Certbot para Nginx, ACME para Traefik)
- ☐ Configurar reverse_proxy para APIs backend
- ☐ Activar HTTP/3 se suportado
- ☐ Optimizar PHP-FPM (pm.max_children, pm.max_requests)
- ☐ Activar OPcache no PHP
- ☐ Configurar compressão (gzip/zstd)
- ☐ Configurar cache de ficheiros estáticos
- ☐ Configurar rate limiting
- ☐ Activar slow log no PHP-FPM
- ☐ Testar com ab/wrk (benchmark)
- ☐ Configurar logs estruturados
- ☐ Documentar configuração
Artigos Relacionados
- Caddy Reverse Proxy com HTTPS
- Traefik Ingress para Kubernetes
- Cloudflare Tunnel: Zero Trust sem VPN
- Postfix SMTP Relay para PME
- Grafana para PMEs: Dashboards com Prometheus
Inspirado na análise técnica de agwa.name sobre FastCGI vs HTTP para reverse proxies. Benchmarks aproximados para referencia — resultados reais dependem de hardware, configuração e workload. Licença: CC BY-SA 4.0.
