12 min de leitura · Guia técnico
Checklist Nginx em produção é uma sequência de verificações técnicas que garante configuração segura, performática e estável antes de publicar alterações no servidor web. Para validar seu Nginx antes do deploy, siga estes 12 passos:
- Validar sintaxe com
nginx -te revisar comnginx -T - Ajustar
worker_processeseworker_connectionsconforme hardware - Configurar TLS 1.2/1.3 com ciphers modernos e OCSP stapling
- Aplicar headers de segurança (HSTS, CSP, X-Frame-Options)
- Habilitar rate limiting e limit_conn contra abuso
- Ativar compressão gzip ou brotli para assets estáticos
- Configurar logs estruturados e logrotate
- Revisar permissões de diretórios e usuário do processo
- Testar reload sem downtime antes do deploy final
- Validar firewall liberando somente portas 80 e 443
- Habilitar stub_status para monitoramento
- Executar teste de carga e verificar respostas HTTP
Pré-requisitos para aplicar o checklist
- Acesso root ou sudo ao servidor Linux (Debian 12, Ubuntu 24.04 LTS, Rocky Linux 9 ou AlmaLinux 9)
- Nginx 1.24 ou superior (recomendado Nginx 1.26 estável)
- Certificado SSL válido (Let's Encrypt via Certbot ou comercial)
- Firewall instalado (UFW, firewalld ou nftables)
- Ferramentas auxiliares:
curl,openssl,ss,htop - Backup da configuração atual em
/etc/nginx/antes de qualquer alteração
Atenção: sempre faça snapshot do VPS ou cópia completa de /etc/nginx antes de aplicar mudanças em produção. Um erro em nginx.conf pode derrubar todos os sites hospedados.
1 a 4: Validação de sintaxe, workers e TLS
A base de qualquer checklist Nginx em produção começa pela validação estrutural do arquivo de configuração. O binário do Nginx oferece dois comandos indispensáveis antes de aplicar qualquer reload.
Passo 1 — Validar sintaxe com nginx -t e nginx -T
sudo nginx -t
sudo nginx -T | less
Output esperado:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
O -T imprime a configuração completa já interpretada, incluindo includes, permitindo revisar diretivas efetivas e detectar conflitos entre server blocks.
Passo 2 — Ajustar worker_processes e worker_connections
No bloco principal de /etc/nginx/nginx.conf, dimensione os workers conforme a CPU disponível:
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 4096;
multi_accept on;
use epoll;
}
Antes de aumentar worker_connections, verifique o limite de descritores de arquivo do sistema:
ulimit -n
cat /proc/sys/fs/file-max
Passo 3 — Configurar TLS 1.2 e 1.3 com ciphers modernos
Desative protocolos obsoletos (SSLv3, TLS 1.0 e 1.1) e ative apenas suítes recomendadas pelo Mozilla:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
Passo 4 — Aplicar headers de segurança
Configure cabeçalhos HTTP no bloco server que atende HTTPS:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'" always;
Você pode validar os headers externamente com curl -I https://seudominio.com.br ou usar scanners como SSL Labs e securityheaders.com.
5 a 8: Rate limiting, compressão, logs e permissões
Após garantir TLS e headers, o próximo bloco do checklist foca em defesa contra abuso, otimização de entrega e observabilidade. Essas quatro verificações reduzem custo de banda e protegem contra picos anômalos de tráfego.
Passo 5 — Habilitar rate limiting
Defina zonas de limite em http {} e aplique em rotas sensíveis:
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
location /wp-login.php {
limit_req zone=login burst=10 nodelay;
limit_conn addr 20;
}
}
Passo 6 — Ativar compressão gzip ou brotli
gzip on;
gzip_vary on;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml image/svg+xml;
Em sites com muitos assets estáticos, o ganho percebido em tempo de carregamento costuma ser relevante, especialmente em conexões móveis. Para saber mais sobre otimização de entrega, consulte Dicas de Otimização de Servidores Linux.
Passo 7 — Configurar logs estruturados
log_format main_ext '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
access_log /var/log/nginx/access.log main_ext;
error_log /var/log/nginx/error.log warn;
Verifique o logrotate em /etc/logrotate.d/nginx para garantir rotação diária e retenção de pelo menos 14 dias, evitando que o disco encha silenciosamente.
Passo 8 — Revisar permissões e usuário
ps aux | grep nginx
ls -la /var/www/
ls -la /etc/nginx/
O processo master roda como root, mas os workers devem executar como www-data (Debian/Ubuntu) ou nginx (Rocky/AlmaLinux). Os arquivos do site devem pertencer ao usuário da aplicação, nunca com chmod 777.
9 a 12: Reload seguro, firewall, monitoramento e teste de carga
A etapa final do checklist Nginx valida o comportamento em runtime. É aqui que muitos deploys falham: a configuração passa no nginx -t, mas a aplicação quebra por conta de firewall, upstream inacessível ou falta de métricas para diagnóstico.
Passo 9 — Reload sem downtime
Após validar a sintaxe, aplique mudanças com reload (não restart):
sudo systemctl reload nginx
sudo systemctl status nginx --no-pager
O reload envia SIGHUP ao processo master, que carrega a nova configuração e encerra workers antigos apenas depois que finalizam conexões ativas — zero interrupção para usuários.
Passo 10 — Validar firewall
Confirme que apenas portas necessárias estão expostas. Em UFW:
sudo ufw status verbose
sudo ss -tlnp | grep nginx
Output esperado:
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1234,fd=6))
LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=1234,fd=7))
Passo 11 — Habilitar stub_status
server {
listen 127.0.0.1:8080;
server_name _;
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
Consulte as métricas com curl http://127.0.0.1:8080/nginx_status. Para dashboards completos, integre com Prometheus via nginx-prometheus-exporter e Grafana.
Passo 12 — Teste de carga e validação HTTP
curl -I -k https://seudominio.com.br
curl --resolve seudominio.com.br:443:127.0.0.1 https://seudominio.com.br
ab -n 1000 -c 50 https://seudominio.com.br/
Verifique códigos de resposta, tempo médio, taxa de erro e se os headers de segurança aparecem corretamente antes de liberar tráfego real para o novo deploy.
Problemas comuns e como resolver
Sintoma: nginx -t retorna "bind() to 0.0.0.0:443 failed (98: Address already in use)"
Causa: outro processo já ocupa a porta 443, geralmente um Apache antigo ou uma instância anterior do Nginx que não finalizou.
Solução: identifique com sudo ss -tlnp | grep :443 e pare o serviço conflitante com sudo systemctl stop apache2. Depois execute sudo systemctl start nginx e valide novamente.
Sintoma: erro 502 Bad Gateway após reload
Causa: o upstream (PHP-FPM, Node.js, Gunicorn) não está escutando no socket ou porta configurada, ou há problema de permissão no socket Unix.
Solução: verifique com sudo systemctl status php8.3-fpm, confirme o caminho em fastcgi_pass e cheque permissões do socket em /run/php/. Ajuste listen.owner e listen.group no pool do PHP-FPM para www-data.
Sintoma: SSL handshake falhando em clientes antigos
Causa: desativação de TLS 1.0/1.1 pode quebrar compatibilidade com sistemas legados ou gateways de pagamento desatualizados.
Solução: mapeie previamente os clientes críticos. Se for obrigatório manter compatibilidade, use TLS 1.2 com ciphers intermediários, nunca reabilite TLS 1.0. Teste com openssl s_client -connect seudominio.com.br:443 -tls1_2.
Sintoma: logs crescendo e consumindo todo o disco
Causa: logrotate ausente ou mal configurado, combinado com access_log verboso em sites de alto tráfego.
Solução: configure /etc/logrotate.d/nginx com rotação diária, compressão e retenção adequada. Para endpoints internos (healthchecks, status), use access_log off; para reduzir volume.
Perguntas frequentes sobre checklist Nginx em produção
O que não pode faltar em um checklist Nginx antes do deploy?
Um checklist Nginx de produção deve cobrir validação de sintaxe com nginx -t, ajuste de worker_processes e worker_connections, configuração de TLS 1.2/1.3 com ciphers modernos, headers de segurança como HSTS e X-Frame-Options, rate limiting, gzip ou brotli, logs estruturados e firewall liberando apenas portas 80 e 443.
Como testar a configuração do Nginx antes de aplicar em produção?
Execute nginx -t para validar a sintaxe dos arquivos, depois nginx -T para imprimir a configuração completa interpretada e revisar cada diretiva. Após confirmar que não há erros, use systemctl reload nginx em vez de restart, pois o reload aplica as mudanças sem derrubar conexões ativas.
Quais headers de segurança são obrigatórios no Nginx?
Os headers essenciais são Strict-Transport-Security (HSTS), X-Content-Type-Options, X-Frame-Options, Referrer-Policy e Content-Security-Policy. Eles protegem contra ataques de downgrade TLS, MIME sniffing, clickjacking e vazamento de informações sensíveis em cabeçalhos de referência.
Qual o valor ideal para worker_processes e worker_connections?
Defina worker_processes como auto para que o Nginx detecte automaticamente o número de cores da CPU. Para worker_connections, comece com 1024 e aumente até 4096 ou 8192 em servidores de alto tráfego, sempre verificando o limite do sistema com ulimit -n antes de ajustar.
Como monitorar se o Nginx está saudável em produção?
Habilite o módulo stub_status em um endpoint interno restrito por IP para expor métricas de conexões ativas, aceitas e handled. Integre com Prometheus via nginx-exporter ou consulte os logs de access e error com logrotate configurado para rotação diária e retenção de pelo menos 14 dias.
Conclusão
- Automatize os 12 passos em um script shell ou playbook Ansible para executar antes de cada deploy — consistência elimina erro humano.
- Mantenha um runbook com
nginx -t,reloade rollback rápido (restaurarnginx.conf.bak) documentado e acessível ao time. - Revise o checklist trimestralmente: ciphers TLS, headers recomendados e versões estáveis do Nginx evoluem, e configurações consideradas seguras hoje podem ficar defasadas em 6 meses.
Leia também
- Otimizar Nginx + PHP-FPM no mesmo servidor: conflitos
- O que é Servidor Proxy Reverso e Como Configurá-lo
- Passo a passo para configurar Nginx com PHP-FPM no VPS Linux: Guia Completo
Precisa de ajuda com Nginx em produção?
Um VPS Linux bem dimensionado é a base para rodar Nginx com TLS moderno, rate limiting e monitoramento contínuo sem gargalos. Nossa equipe pode orientar o plano ideal para sua carga de trabalho.