O Nginx é um dos servidores web mais rápidos e eficientes do mercado. Enquanto o Apache dominou a web por décadas, o Nginx se tornou a escolha preferida para sites de alta performance, incluindo WordPress.
Neste tutorial completo, você vai aprender a instalar e configurar o Nginx para rodar WordPress de forma otimizada, com PHP-FPM, cache, SSL e todas as boas práticas de segurança e performance.
Nginx vs Apache: Por Que Escolher Nginx
Antes de mergulhar na configuração, vale entender por que o Nginx é uma excelente escolha para WordPress.
Arquitetura
- Apache: cria um processo ou thread para cada conexão simultânea. Sob alta carga, o consumo de memória cresce rapidamente.
- Nginx: usa uma arquitetura event-driven com um número fixo de worker processes. Cada worker lida com milhares de conexões simultâneas sem criar processos adicionais.
Performance
- Arquivos estáticos: Nginx serve arquivos estáticos (CSS, JS, imagens) até 2x mais rápido que o Apache
- Uso de memória: Nginx consome significativamente menos memória sob carga
- Conexões simultâneas: Nginx lida com 10.000+ conexões sem degradação perceptível
Quando o Apache ainda faz sentido
- Hospedagem compartilhada com .htaccess (Nginx não suporta .htaccess)
- Plugins que dependem de regras mod _ rewrite específicas do Apache
- Ambientes onde a simplicidade de configuração é prioridade
Para WordPress em VPS ou servidor dedicado, o Nginx é a escolha recomendada.
Instalando Nginx no Ubuntu
Este tutorial usa Ubuntu 22.04/24.04 LTS, a distribuição mais comum para servidores web.
Atualizar o sistema
sudo apt update && sudo apt upgrade -y
Instalar o Nginx
sudo apt install nginx -y
Verificar a instalação
sudo systemctl status nginx nginx -v
Iniciar e habilitar no boot
sudo systemctl start nginx sudo systemctl enable nginx
Configurar o firewall
# Permitir tráfego HTTP e HTTPS sudo ufw allow 'Nginx Full' sudo ufw enable sudo ufw status
Neste ponto, ao acessar o IP do servidor no navegador, você deve ver a página padrão do Nginx.
Instalando PHP-FPM
O WordPress precisa de PHP para funcionar. Com Nginx, usamos PHP-FPM (FastCGI Process Manager) para processar scripts PHP.
Instalar PHP e módulos necessários
sudo apt install php8.2-fpm php8.2-mysql php8.2-curl php8.2-gd \ php8.2-mbstring php8.2-xml php8.2-zip php8.2-intl \ php8.2-imagick php8.2-opcache php8.2-soap php8.2-bcmath -y
Verificar a instalação
php -v sudo systemctl status php8.2-fpm
Configurar o PHP-FPM
Edite o arquivo de configuração do pool:
sudo nano /etc/php/8.2/fpm/pool.d/www.conf
Configurações recomendadas para um VPS com 4-8GB de RAM:
; Modo de gerenciamento de processos pm = dynamic ; Número máximo de processos filhos pm.max_children = 25 ; Processos iniciais pm.start_servers = 5 ; Mínimo de processos ociosos pm.min_spare_servers = 3 ; Máximo de processos ociosos pm.max_spare_servers = 10 ; Requests antes de reciclar o processo (previne memory leaks) pm.max_requests = 500 ; Timeout para processos lentos request_terminate_timeout = 300
Configurar o php.ini
sudo nano /etc/php/8.2/fpm/php.ini
Configurações recomendadas para WordPress:
upload_max_filesize = 64M post_max_size = 64M memory_limit = 256M max_execution_time = 300 max_input_time = 300 max_input_vars = 3000
Reiniciar PHP-FPM
sudo systemctl restart php8.2-fpm
Server Block para WordPress
O "server block" do Nginx é equivalente ao "virtual host" do Apache. Aqui configuramos como o Nginx vai servir o site WordPress.
Criar o server block
sudo nano /etc/nginx/sites-available/seusite.com.br
Configuração básica funcional:
server {
listen 80;
listen [::]:80;
server_name seusite.com.br www.seusite.com.br;
root /var/www/seusite.com.br;
index index.php index.html;
# Logs
access_log /var/log/nginx/seusite-access.log;
error_log /var/log/nginx/seusite-error.log;
# Tamanho máximo de upload
client_max_body_size 64M;
# Rewrite de permalinks do WordPress
location / {
try_files $uri $uri/ /index.php?$args;
}
# Processar PHP via PHP-FPM
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_read_timeout 300;
}
# Bloquear acesso a arquivos ocultos
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# Cache de arquivos estáticos
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|webp|avif|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
}
# Bloquear acesso ao wp-config.php
location = /wp-config.php {
deny all;
}
# Bloquear acesso ao xmlrpc.php (alvo frequente de ataques)
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
}
# Bloquear listagem de diretórios
autoindex off;
}
Ativar o server block
# Criar link simbólico sudo ln -s /etc/nginx/sites-available/seusite.com.br /etc/nginx/sites-enabled/ # Remover o site padrão (opcional) sudo rm /etc/nginx/sites-enabled/default # Testar a configuração sudo nginx -t # Recarregar o Nginx sudo systemctl reload nginx
Rewrite de Permalinks
No Apache, os permalinks do WordPress são configurados via .htaccess . No Nginx, usamos a diretiva try_files no server block.
A linha chave é:
location / {
try_files $uri $uri/ /index.php?$args;
}
Essa regra faz o seguinte:
- Tenta servir o arquivo diretamente ( $uri )
- Tenta servir como diretório ( $uri/ )
- Se nenhum dos dois existe, encaminha para index.php com os argumentos (query string)
Isso é tudo que o WordPress precisa para que os permalinks bonitos funcionem (ex: /meu-post/ em vez de /?p=123 ).
Configuração no WordPress
Após configurar o Nginx, acesse Configurações > Links Permanentes no painel do WordPress e selecione a estrutura desejada (recomendado: "Nome do post" ou estrutura personalizada /%postname%/ ).
Headers de Segurança
Headers HTTP de segurança protegem seu site contra diversos tipos de ataques. Adicione-os dentro do bloco server :
# Headers de segurança add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; # Content Security Policy (ajuste conforme necessário) # add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';" always;
O CSP (Content Security Policy) está comentado porque pode quebrar plugins e temas que usam scripts inline. Habilite e ajuste conforme necessário.
Proteções adicionais no server block
# Bloquear acesso a arquivos sensíveis
location ~* /(wp-config\.php|readme\.html|license\.txt|wp-includes/.*\.php) {
deny all;
}
# Bloquear execução de PHP em diretórios de upload
location ~* /wp-content/uploads/.*\.php$ {
deny all;
}
# Limitar métodos HTTP aceitos
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 444;
}
Cache com FastCGI Cache
O FastCGI Cache do Nginx é uma das formas mais eficientes de cache para WordPress. Ele armazena a resposta PHP completa em disco e serve diretamente, sem passar pelo PHP-FPM.
Configurar a zona de cache
No arquivo principal do Nginx ( /etc/nginx/nginx.conf ), dentro do bloco http :
http {
# Definir zona de cache
fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2
keys_zone=WORDPRESS:100m
inactive=60m
max_size=512m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout updating http_500 http_503;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
}
Adicionar cache ao server block
server {
# Variáveis de controle do cache
set $skip_cache 0;
# Não cachear requisições POST
if ($request_method = POST) {
set $skip_cache 1;
}
# Não cachear URLs com query strings
if ($query_string != "") {
set $skip_cache 1;
}
# Não cachear páginas do admin, login, carrinho e checkout
if ($request_uri ~* "/wp-admin/|/wp-login.php|/xmlrpc.php|/cart/|/checkout/|/my-account/") {
set $skip_cache 1;
}
# Não cachear para usuários logados ou com itens no carrinho
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in|woocommerce_items_in_cart") {
set $skip_cache 1;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# Configuração do cache
fastcgi_cache WORDPRESS;
fastcgi_cache_valid 200 301 302 60m;
fastcgi_cache_valid 404 1m;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
# Header para debug (remova em produção)
add_header X-FastCGI-Cache $upstream_cache_status;
}
}
Criar o diretório de cache
sudo mkdir -p /var/cache/nginx/fastcgi sudo chown www-data:www-data /var/cache/nginx/fastcgi
Limpar o cache
# Limpar todo o cache sudo rm -rf /var/cache/nginx/fastcgi/* # Ou use o plugin Nginx Helper no WordPress para limpar # automaticamente quando conteúdo é atualizado
SSL com Let's Encrypt e Certbot
HTTPS é obrigatório para qualquer site moderno. O Let's Encrypt oferece certificados SSL gratuitos, e o Certbot automatiza a instalação e renovação.
Instalar o Certbot
sudo apt install certbot python3-certbot-nginx -y
Obter o certificado
sudo certbot --nginx -d seusite.com.br -d www.seusite.com.br
O Certbot vai:
- Verificar a propriedade do domínio
- Obter o certificado SSL
- Configurar o Nginx automaticamente para HTTPS
- Adicionar redirecionamento HTTP para HTTPS
Verificar a renovação automática
# Testar renovação sudo certbot renew --dry-run # Verificar o timer do systemd sudo systemctl status certbot.timer
O Certbot configura automaticamente a renovação. Os certificados Let's Encrypt expiram a cada 90 dias, mas o Certbot os renova automaticamente.
Configuração SSL otimizada
Após o Certbot gerar a configuração, melhore a segurança SSL adicionando ao server block HTTPS:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name seusite.com.br www.seusite.com.br;
ssl_certificate /etc/letsencrypt/live/seusite.com.br/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/seusite.com.br/privkey.pem;
# Protocolos e cifras
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
# HSTS (forçar HTTPS por 1 ano)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Session
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# ... resto da configuração do site
}
# Redirecionar HTTP para HTTPS
server {
listen 80;
listen [::]:80;
server_name seusite.com.br www.seusite.com.br;
return 301 https://$server_name$request_uri;
}
Compressão Gzip
Gzip comprime as respostas do servidor antes de enviá-las ao navegador, reduzindo significativamente o tráfego.
Adicione ao bloco http no /etc/nginx/nginx.conf :
# Compressão Gzip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_min_length 256;
gzip_types
text/plain
text/css
text/javascript
text/xml
application/json
application/javascript
application/xml
application/xml+rss
application/x-javascript
application/vnd.ms-fontobject
font/opentype
image/svg+xml
image/x-icon;
Brotli (alternativa mais eficiente)
Se quiser compressão ainda melhor, instale o módulo Brotli:
sudo apt install libnginx-mod-http-brotli-filter libnginx-mod-http-brotli-static -y
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css text/javascript application/json
application/javascript application/xml image/svg+xml;
Otimização de Performance
Worker processes e conexões
No /etc/nginx/nginx.conf :
# Número de workers = número de CPUs
worker_processes auto;
# Número máximo de conexões por worker
events {
worker_connections 2048;
multi_accept on;
use epoll;
}
http {
# Keepalive
keepalive_timeout 30;
keepalive_requests 100;
# Buffers
client_body_buffer_size 16K;
client_header_buffer_size 1k;
large_client_header_buffers 4 16k;
# Timeouts
client_body_timeout 12;
client_header_timeout 12;
send_timeout 10;
# Sendfile (servir arquivos diretamente do kernel)
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# Desativar exibição da versão do Nginx
server_tokens off;
# Limitar taxa de requisições (proteção contra DDoS básico)
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
}
Open file cache
open_file_cache max=10000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on;
Problemas Comuns e Debug
Erro 502 Bad Gateway
Significa que o Nginx não consegue se comunicar com o PHP-FPM.
Verificações:
# PHP-FPM está rodando? sudo systemctl status php8.2-fpm # O socket existe? ls -la /var/run/php/php8.2-fpm.sock # Logs do PHP-FPM sudo tail -f /var/log/php8.2-fpm.log
Erro 403 Forbidden
Geralmente um problema de permissões:
# Corrigir permissões do WordPress
sudo chown -R www-data:www-data /var/www/seusite.com.br/
sudo find /var/www/seusite.com.br/ -type f -exec chmod 644 {} \;
sudo find /var/www/seusite.com.br/ -type d -exec chmod 755 {} \;
Erro 404 em todas as páginas (exceto home)
Os permalinks não estão configurados corretamente. Verifique se o try_files está presente:
location / {
try_files $uri $uri/ /index.php?$args;
}
Upload falha com erro de tamanho
Ajuste o client_max_body_size no server block:
client_max_body_size 64M;
E também no php.ini :
upload_max_filesize = 64M post_max_size = 64M
Testar e recarregar a configuração
Sempre teste antes de recarregar:
# Testar configuração sudo nginx -t # Recarregar (sem downtime) sudo systemctl reload nginx # Reiniciar (com breve downtime) sudo systemctl restart nginx
Monitoramento
Habilitar o status do Nginx
# Adicione ao server block ou em um bloco separado
location /nginx_status {
stub_status on;
allow 127.0.0.1;
deny all;
}
Monitorar logs em tempo real
# Access log
sudo tail -f /var/log/nginx/seusite-access.log
# Error log
sudo tail -f /var/log/nginx/seusite-error.log
# Requisições por segundo
sudo tail -f /var/log/nginx/seusite-access.log | awk '{print $4}' | uniq -c
Ferramentas de monitoramento
- Netdata: monitoramento em tempo real do servidor, Nginx e PHP-FPM
- GoAccess: análise de logs do Nginx em terminal ou HTML
- Munin: gráficos históricos de performance
Leia Também
- Site WordPress Lento? 10 Causas e Como Resolver Cada Uma
- Como Otimizar Imagens no WordPress sem Perder Qualidade
Conclusão
Configurar Nginx para WordPress exige mais passos manuais do que o Apache, mas o resultado em performance e eficiência compensa o esforço. Com PHP-FPM otimizado, FastCGI Cache, SSL via Let's Encrypt e compressão gzip, seu site WordPress vai carregar significativamente mais rápido.
Lembre-se de sempre testar a configuração ( nginx -t ) antes de recarregar e mantenha backups das configurações funcionais.
Precisa de ajuda para configurar e otimizar o servidor do seu WordPress? A HOSTWP cuida de tudo, do servidor ao site. Nossa equipe configura Nginx, PHP-FPM, cache, SSL e toda a infraestrutura para que seu site tenha performance máxima e segurança de nível profissional. Entre em contato e deixe o servidor com quem entende.