Configuração Nginx com Cache para WordPress em Produção

arquitetura de servidor web em produção é onde teoria e vida real se encontram 😄
Vou te mostrar o modelo ideal (moderno, estável e escalável) e depois explico por que cada peça existe.

Implementar cache no Nginx é uma das formas mais eficientes de reduzir a carga de processamento em servidores WordPress. Mesmo assim, durante picos de tráfego ou campanhas de marketing, o servidor ainda pode precisar lidar com aumentos temporários no uso de CPU. Em ambientes VPS, esses picos podem ser absorvidos por mecanismos como o burst de CPU em VPS.


Arquitetura ideal (visão geral)

        🌍 Internet
            |
     🌐 CDN / WAF (Cloudflare)
            |
     🔒 Load Balancer (L4/L7)
            |
    ┌─────────────────────┐
    │  Nginx (Reverse)    │
    │  TLS + Cache        │
    └─────────┬───────────┘
              |
       ┌─────────────┐
       │ PHP-FPM     │
       │ (isolado)   │
       └──────┬──────┘
              |
       ┌─────────────┐
       │ Banco (DB)  │
       │ MariaDB     │
       └─────────────┘
              |
       ┌─────────────┐
       │ Redis       │
       │ Cache/Sess. │
       └─────────────┘

Camada por camada (o porquê)

1️⃣ CDN + WAF (Cloudflare, Fastly, etc.)

Função

  • Bloqueia ataque antes de chegar no servidor
  • Cacheia estático globalmente
  • Reduz latência absurda

Em produção real

  • Rate limit
  • Bot management
  • TLS + HTTP/3

👉 Sem CDN hoje, você está desperdiçando recursos.


2️⃣ Load Balancer (opcional, mas ideal)

Pode ser:

  • Cloud (AWS ELB, HAProxy cloud)
  • Local (HAProxy, Nginx)

Serve para

  • Alta disponibilidade
  • Escalar horizontalmente
  • Zero-downtime deploy

Mesmo com 1 servidor, já vale deixar o desenho preparado.


3️⃣ Nginx (Reverse Proxy)

Aqui é onde muita gente erra.

Responsabilidades

  • TLS termination
  • HTTP/2 e HTTP/3
  • Cache de páginas
  • Entregar estático
  • Proxy para PHP-FPM

Por que não Apache direto?

  • Nginx é event-driven
  • Apache com PHP é pesado para concorrência

👉 Apache só faz sentido atrás do Nginx ou para legacy.


4️⃣ PHP-FPM isolado

Nunca misture tudo no mesmo pool.

Boas práticas:

  • Pool por site
  • Usuário separado
  • pm = ondemand ou dynamic
  • pm.max_children calculado

Isso evita:

  • Um site derrubar o outro
  • Memory leak em efeito dominó

5️⃣ Banco de dados separado (ou bem ajustado)

Ideal:

  • DB em outro servidor
  • Replicação
  • Backups automáticos

Em VPS única:

  • MariaDB bem ajustado
  • Buffer pool ≈ 60–70% da RAM disponível
  • Slow query log ativo

6️⃣ Redis (essencial hoje)

Usos

  • Cache de objeto (WordPress, Laravel)
  • Sessões
  • Filas leves

Resultado:

  • Menos acesso ao banco
  • Menos CPU
  • Resposta mais rápida

Redis mal configurado é comum — mas Redis bem usado é mágico.


7️⃣ Sistema operacional (base sólida)

Linux minimal

  • Ubuntu LTS / AlmaLinux / Rocky
  • Sem serviços inúteis
  • Swap controlado
  • I/O scheduler correto
  • MTU certo
  • Time sync (chrony)

A maioria dos “problemas misteriosos” vem daqui.

Estratégias de cache ajudam a diminuir o número de requisições processadas pelo PHP e pelo banco de dados, reduzindo significativamente o consumo de CPU do servidor. Mesmo assim, picos de acesso ainda podem ocorrer em aplicações web populares. Em ambientes virtualizados, entender como funciona o burst de CPU em servidores VPS pode ajudar a lidar com esses momentos de alta demanda.


Arquitetura ideal na prática (VPS única)

Se fosse montar hoje, eu faria:

  • Cloudflare (CDN + WAF)
  • Nginx
  • PHP-FPM (pools separados)
  • Redis
  • MariaDB
  • Backups offsite
  • Monitoramento (Netdata / Prometheus)

👉 Isso segura milhares de usuários simultâneos sem drama.


Erros clássicos em produção

❌ Apache + PHP mod_php
❌ Tudo rodando como root
❌ Sem cache nenhum
❌ Banco disputando RAM com PHP
❌ Swap descontrolado
❌ Sem monitoramento
❌ “Uptime alto” mas sistema travando


Regra de ouro

Produção não é sobre funcionar.
É sobre continuar funcionando sob pressão.

Vamos desenhar a arquitetura ideal de WordPress em produção, do jeito que aguenta tráfego, update mal-feito, plugin ruim e ataque, sem drama 😄

Vou mostrar o desenho, depois o papel exato de cada camada, e no fim 3 variações práticas (VPS única, alta disponibilidade e WooCommerce).


🧱 Arquitetura ideal de WordPress (visão clara)

                🌍 Internet
                     |
            🌐 CDN + WAF (Cloudflare)
         Cache | Bot | Rate Limit | TLS
                     |
             🔁 Load Balancer (L7)
               (opcional, ideal)
                     |
        ┌───────────────────────────┐
        │        NGINX               │
        │ Reverse Proxy + Cache      │
        │ HTTP/2 | HTTP/3 | Brotli   │
        └──────────────┬────────────┘
                       |
                ┌────────────┐
                │  PHP-FPM   │
                │ Pool WP    │
                └──────┬─────┘
                       |
      ┌────────────────┼────────────────┐
      |                |                |
┌────────────┐   ┌────────────┐   ┌────────────┐
│   Redis    │   │  MariaDB   │   │  Storage   │
│ Object     │   │   / MySQL  │   │ Uploads    │
│ Cache      │   │            │   │ (local/S3) │
└────────────┘   └────────────┘   └────────────┘

🔍 Função real de cada camada

🌐 1️⃣ CDN + WAF (Cloudflare)

Indispensável em WordPress moderno

  • Cache HTML
  • Bloqueio de bots
  • Rate limiting (wp-login, xmlrpc)
  • TLS offload
  • HTTP/3

👉 Sem isso, WordPress vira alvo fácil.


🔁 2️⃣ Load Balancer (opcional, mas futuro-proof)

Usado quando:

  • Mais de 1 servidor web
  • Zero-downtime deploy
  • WooCommerce grande

Pode ser:

  • Cloud (AWS / GCP)
  • HAProxy / Nginx

⚡ 3️⃣ Nginx (Reverse Proxy)

Aqui mora o ganho de performance.

Responsabilidades:

  • Cache FastCGI
  • Servir estático
  • Proxy para PHP-FPM
  • Compressão
  • Headers de segurança

Nunca use WordPress direto no Apache em produção pesada.


🐘 4️⃣ PHP-FPM (isolado)

Regra de ouro: 1 pool por site

Configuração típica:

  • pm = ondemand
  • pm.max_children calculado
  • Memory limit controlado

Resultado:

  • Plugin ruim não derruba tudo
  • Uso de RAM previsível

🚀 5️⃣ Redis (Object Cache)

Essencial para WordPress.

Cache:

  • Queries
  • Transients
  • Sessões

Plugins comuns:

  • Redis Object Cache
  • WP Rocket (integrando)

👉 Reduz carga no banco absurdamente.


🗄️ 6️⃣ Banco de dados (MariaDB)

Boas práticas:

  • Buffer Pool grande
  • Slow query log ativo
  • Tabelas otimizadas
  • Índices corretos

Em sites grandes:

  • DB separado
  • Réplica de leitura

📁 7️⃣ Storage (uploads)

Opções:

  • Local (sites pequenos)
  • S3 / R2 / MinIO (ideal)
  • CDN puxando direto

Evita:

  • I/O local excessivo
  • Problemas em cluster

🧪 Arquiteturas práticas

🔹 VPS Única (90% dos casos)

Cloudflare
   |
 Nginx
   |
PHP-FPM
 |    \
Redis  MariaDB

✔ Rápida
✔ Simples
✔ Barata


🔹 Alta disponibilidade

Cloudflare
   |
 Load Balancer
   |
Nginx x2
   |
PHP-FPM x2
   |
Redis + DB

✔ Escala horizontal
✔ Sem downtime


🔹 WooCommerce pesado

Cloudflare (Cache OFF p/ carrinho)
   |
 Nginx
   |
PHP-FPM (pool dedicado)
   |
Redis (sessões)
   |
MariaDB (separado)

✔ Carrinho estável
✔ Checkout rápido


❌ Erros comuns em WordPress produção

  • Apache + mod_php
  • Cache só via plugin
  • Sem Redis
  • Tudo no mesmo pool
  • Plugins sem controle
  • Sem rate limit
  • wp-cron rodando via web

🧠 Regra de ouro do WordPress

Cache fora do WordPress.
WordPress só gera conteúdo — não protege nem escala.

Então vamos fechar o desenho ideal para WordPress em uma VPS única, do jeito simples, rápido e difícil de derrubar 🔥
Sem overengineering, mas com padrão de produção real.


🧱 Arquitetura WordPress — VPS única (ideal)

                🌍 Internet
                     |
            🌐 Cloudflare (CDN + WAF)
          Cache HTML | Rate limit | TLS
                     |
              ┌───────────────┐
              │    NGINX      │
              │ Reverse Proxy │
              │ FastCGI Cache │
              └───────┬───────┘
                      |
               ┌────────────┐
               │  PHP-FPM   │
               │ Pool WP    │
               └──────┬─────┘
                      |
        ┌─────────────┼─────────────┐
        │             │             │
   ┌──────────┐  ┌──────────┐  ┌──────────┐
   │  Redis   │  │ MariaDB  │  │ Storage  │
   │ ObjCache │  │   DB     │  │ Uploads  │
   └──────────┘  └──────────┘  └──────────┘

🔧 Stack recomendada (sem firula)

  • SO: Ubuntu 22.04 LTS / AlmaLinux 9
  • Web: Nginx
  • PHP: PHP-FPM (8.1 ou 8.2)
  • Cache: Redis
  • DB: MariaDB 10.6+
  • CDN: Cloudflare
  • Backup: Offsite (S3 / R2)

⚙️ Configuração essencial (o que faz diferença)

🌐 Cloudflare

  • Cache everything (exceto /wp-admin, /wp-login.php)
  • Rate limit em:
    • /wp-login.php
    • /xmlrpc.php
  • Brotli + HTTP/3
  • Page Rules simples

⚡ Nginx (core da performance)

Responsabilidades:

  • Servir estático
  • Cache FastCGI
  • Proxy para PHP

Essencial:

  • fastcgi_cache
  • proxy_cache
  • Headers de segurança
  • Gzip/Brotli

👉 90% das requisições nem chegam no PHP.


🐘 PHP-FPM (estabilidade)

Config recomendada:

  • pm = ondemand
  • pm.max_children calculado
  • memory_limit realista
  • request_terminate_timeout

Regra:

Um site = um pool


🚀 Redis (obrigatório)

  • Object Cache
  • Transients
  • Sessões

Plugin:

  • Redis Object Cache (oficial)

Resultado:

  • Menos MySQL
  • Menos CPU
  • Mais estabilidade

🗄️ MariaDB

Boas práticas:

  • innodb_buffer_pool_size ≈ 60% RAM disponível
  • slow_query_log = ON
  • Charset utf8mb4
  • Índices certos

Nunca deixe DB “default”.


🔁 Cron (muita gente erra aqui)

  • Desativar wp-cron via web
  • Criar cron real no sistema
*/5 * * * * php /var/www/site/wp-cron.php

📦 Plugins obrigatórios (enxutos)

✔ Redis Object Cache
✔ Cache leve (WP Rocket / similar)
✔ Segurança (Wordfence / WAF)
✔ Backup offsite

❌ Evitar plugins “milagrosos”


🛡️ Hardening mínimo

  • DISALLOW_FILE_EDIT
  • Permissões corretas
  • Rate limit
  • XML-RPC protegido
  • Headers HTTP

📊 Monitoramento (não opcional)

  • Netdata
  • Log lento do PHP
  • Slow query MySQL
  • Uso real de RAM

Sem monitoramento, você só descobre o problema quando o site cai.


🧠 Regra de ouro (VPS única)

Cache + isolamento > hardware bruto

Uma VPS bem montada vence servidor caro mal configurado.

Abaixo está configuração REAL de Nginx com FastCGI Cache para WordPress em VPS única, pronta pra produção — sem gambiarra e sem “exemplo de blog” 😄

Vou dividir em 3 partes:

  1. Cache global
  2. Server block WordPress
  3. Explicação do que é crítico

1️⃣ Cache FastCGI (config global)

👉 Coloque em /etc/nginx/conf.d/fastcgi-cache.conf

fastcgi_cache_path /var/cache/nginx/wordpress
    levels=1:2
    keys_zone=WORDPRESS:100m
    inactive=60m
    max_size=5g
    use_temp_path=off;

fastcgi_cache_key "$scheme$request_method$host$request_uri";

map $request_method $skip_cache_method {
    default 0;
    POST    1;
}

map $http_cookie $skip_cache_cookie {
    default 0;
    ~*wordpress_logged_in 1;
    ~*comment_author     1;
    ~*woocommerce_items_in_cart 1;
}

map $request_uri $skip_cache_uri {
    default 0;
    ~*/wp-admin/ 1;
    ~*/wp-login.php 1;
    ~*/cart/ 1;
    ~*/checkout/ 1;
    ~*/my-account/ 1;
}

2️⃣ Server block WordPress (produção)

👉 /etc/nginx/sites-available/site.conf

server {
    listen 443 ssl http2;
    server_name site.com www.site.com;

    root /var/www/site/public;
    index index.php;

    ssl_certificate     /etc/letsencrypt/live/site.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/site.com/privkey.pem;

    add_header X-Cache $upstream_cache_status always;

    client_max_body_size 64M;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include fastcgi_params;

        fastcgi_pass unix:/run/php/php8.2-fpm-site.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        fastcgi_cache WORDPRESS;
        fastcgi_cache_valid 200 301 302 60m;
        fastcgi_cache_use_stale error timeout updating http_500 http_503;
        fastcgi_cache_background_update on;
        fastcgi_cache_lock on;

        fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

        fastcgi_no_cache
            $skip_cache_method
            $skip_cache_cookie
            $skip_cache_uri;

        fastcgi_cache_bypass
            $skip_cache_method
            $skip_cache_cookie
            $skip_cache_uri;
    }

    location ~* \.(css|js|jpg|jpeg|png|gif|svg|ico|woff2?)$ {
        expires 30d;
        access_log off;
    }

    location ~ /\. {
        deny all;
    }
}

3️⃣ O que ESSA config resolve (de verdade)

🔥 Performance

  • Cache fora do WordPress
  • 90% das requisições não chegam no PHP
  • Atualização em background (zero pico)

🛡️ Segurança

  • Admin e login fora do cache
  • Cookies respeitados
  • Bloqueio de arquivos ocultos

🧠 Inteligência

  • Cache invalida automaticamente por URL
  • Suporte real a WooCommerce
  • Header X-Cache pra debug (HIT, MISS)

🔎 Como validar

curl -I https://site.com

Procure:

X-Cache: HIT

❌ Erros comuns (evitados aqui)

  • Cache plugin brigando com Nginx
  • Cache em POST
  • Cache de usuário logado
  • WooCommerce quebrando carrinho
  • PHP sobrecarregado sem motivo

🧠 Regra de ouro

Cache no Nginx é previsível.
Cache no WordPress é aposta.

Cache HTTP é uma das estratégias mais eficazes para melhorar a performance de sites WordPress. No entanto, para garantir estabilidade durante picos de acesso, também é importante entender como o servidor gerencia recursos de processamento. Para aprofundar esse tema, veja também o guia sobre configuração de burst de CPU em VPS.

FAQ

Nginx com cache é melhor que plugin de cache no WordPress?

Sim. O cache no Nginx funciona antes do PHP e do WordPress, consumindo menos CPU e memória e sendo muito mais previsível em produção.

FastCGI Cache quebra login ou área administrativa?

Não, desde que URLs como /wp-admin e /wp-login.php e cookies de usuários logados sejam excluídos do cache, como na configuração recomendada.

Posso usar Nginx Cache junto com Redis no WordPress?

Sim. O Nginx cacheia páginas HTML, enquanto o Redis cuida do object cache (queries, transients e sessões). Eles se complementam.

Essa configuração funciona para WooCommerce?

Funciona, mas exige exclusões extras para carrinho, checkout e conta do usuário. Em lojas, o cache deve ser usado com mais cuidado.

Cloudflare ainda é necessário se eu usar cache no Nginx?

Sim. Cloudflare adiciona CDN global, WAF, proteção contra bots e ataques, reduzindo ainda mais a carga no servidor.