Nginx como proxy reverso com cache para WooCommerce é uma camada que fica à frente do servidor de aplicação (Apache ou outro Nginx com PHP-FPM) e entrega cópias prontas das páginas públicas da loja, evitando que cada visitante em um pico acione PHP e banco de dados. O cache sozinho não resolve tudo: sem regras de bypass para carrinho, checkout e usuários logados, ele quebra a loja. Para configurar corretamente no Debian 13, siga estes passos:
- Mova o servidor de aplicação (Apache ou Nginx + PHP-FPM) para a porta 8080, só em 127.0.0.1.
- Instale o Nginx 1.28+ e crie a zona de cache com
proxy_cache_path. - Defina um
mapque ativa o bypass para cookies e URLs do WooCommerce. - Crie o bloco
servercomproxy_pass, TTL curto eproxy_cache_use_stale. - Adicione o header
X-Cache-Statuse valide comcurl -I. - Simule carga e acompanhe HIT/MISS/BYPASS antes do pico real.
Pré-requisitos
- Acesso root ou sudo a um VPS com Debian 13 (Trixie) ou Ubuntu 24.04 LTS.
- WooCommerce em execução com PHP 8.4 atrás de Apache ou Nginx + PHP-FPM.
- Nginx 1.28 ou superior (o pacote
nginxdo repositório oficial serve). - Certificado SSL válido para o domínio da loja (Let's Encrypt via Certbot, por exemplo).
- DNS do domínio apontando para o IP do servidor e portas 80/443 liberadas no firewall.
- Permalinks em português conhecidos:
/carrinho/,/finalizar-compra/,/minha-conta/.
Nginx como proxy reverso com cache para WooCommerce: arquitetura
A arquitetura de proxy reverso com cache separa duas responsabilidades: o Nginx na frente responde às conexões do público, termina o TLS e serve páginas do disco; o backend na porta 8080 só é acionado quando a resposta não está em cache ou quando o visitante tem sessão de compra. Em um pico de Black Friday ou campanha de influenciador, 90% ou mais dos acessos caem em home, categorias e páginas de produto, e são justamente essas que o cache absorve.
Primeiro, mude o backend para escutar apenas localmente. No Apache, edite /etc/apache2/ports.conf:
Listen 127.0.0.1:8080
E ajuste o VirtualHost do site para <VirtualHost 127.0.0.1:8080>. Se o backend for outro Nginx com PHP-FPM, troque o listen 80; por listen 127.0.0.1:8080;. Reinicie e confirme:
sudo systemctl restart apache2
ss -tlnp | grep 8080
LISTEN 0 511 127.0.0.1:8080 0.0.0.0:* users:(("apache2",pid=1842,fd=4))
Agora instale o Nginx frontal:
sudo apt update && sudo apt install -y nginx
nginx -v
nginx version: nginx/1.28.0
Se o site ainda não força HTTPS, consulte como redirecionar um site HTTP para HTTPS — o redirecionamento deve acontecer na camada do proxy, não no backend, para não gerar loops.
Configurar a zona de proxy_cache e as regras de bypass
A zona de cache do Nginx define onde os arquivos ficam, quanto espaço ocupam e por quanto tempo permanecem. Crie o arquivo /etc/nginx/conf.d/woo-cache.conf:
proxy_cache_path /var/cache/nginx/woo levels=1:2 keys_zone=woo:100m
max_size=2g inactive=30m use_temp_path=off;
map $http_cookie $woo_skip_cookie {
default 0;
~*woocommerce_items_in_cart 1;
~*woocommerce_cart_hash 1;
~*wp_woocommerce_session_ 1;
~*wordpress_logged_in_ 1;
~*comment_author_ 1;
}
map $request_uri $woo_skip_uri {
default 0;
~*^/carrinho/ 1;
~*^/finalizar-compra/ 1;
~*^/minha-conta/ 1;
~*^/wp-admin/ 1;
~*^/wp-login.php 1;
~*^/\?wc-ajax= 1;
~*^/wp-json/ 1;
~*\?add-to-cart= 1;
}
map "$woo_skip_cookie$woo_skip_uri$request_method" $woo_skip {
default 1;
"00GET" 0;
"00HEAD" 0;
}
O terceiro map combina as condições: só GET e HEAD sem cookie de sessão e fora das URLs sensíveis recebem valor 0 (cacheável). Qualquer POST — inclusive o envio do formulário de pedido — passa direto. Crie o diretório e ajuste o dono:
sudo mkdir -p /var/cache/nginx/woo
sudo chown www-data:www-data /var/cache/nginx/woo
Agora o bloco server em /etc/nginx/sites-available/seudominio.com.br:
server {
listen 443 ssl;
http2 on;
server_name seudominio.com.br www.seudominio.com.br;
ssl_certificate /etc/letsencrypt/live/seudominio.com.br/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/seudominio.com.br/privkey.pem;
client_max_body_size 64m;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
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 https;
proxy_cache woo;
proxy_cache_key "$scheme$host$request_uri";
proxy_cache_valid 200 301 302 2m;
proxy_cache_valid 404 30s;
proxy_cache_bypass $woo_skip;
proxy_no_cache $woo_skip;
proxy_ignore_headers Cache-Control Expires Set-Cookie;
proxy_hide_header Set-Cookie;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
proxy_cache_background_update on;
proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
add_header X-Cache-Status $upstream_cache_status;
}
}
server {
listen 80;
server_name seudominio.com.br www.seudominio.com.br;
return 301 https://$host$request_uri;
}
Atenção: proxy_hide_header Set-Cookie só é aplicado a respostas que entram no cache; respostas com $woo_skip = 1 nunca são armazenadas, então o cookie de sessão chega normalmente ao cliente. Se você remover o proxy_no_cache, uma página de carrinho pode ser gravada e entregue a outro visitante — esse é o vazamento clássico de dados em lojas mal configuradas.
No wp-config.php, garanta que o WordPress reconheça o HTTPS vindo do proxy:
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
Valide e recarregue:
sudo nginx -t && sudo systemctl reload nginx
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Testar o cache HTTP sob carga antes do pico
Testar o cache HTTP antes do evento evita descobrir problemas com clientes reais. Faça duas requisições seguidas à home:
curl -sI https://seudominio.com.br/ | grep -i x-cache
curl -sI https://seudominio.com.br/ | grep -i x-cache
X-Cache-Status: MISS
X-Cache-Status: HIT
Agora simule um visitante com carrinho e uma URL de checkout:
curl -sI -H "Cookie: woocommerce_items_in_cart=1" https://seudominio.com.br/ | grep -i x-cache
curl -sI https://seudominio.com.br/finalizar-compra/ | grep -i x-cache
X-Cache-Status: BYPASS
X-Cache-Status: BYPASS
Para medir o ganho real de TTFB, compare o tempo até o primeiro byte entre MISS e HIT:
curl -so /dev/null -w "TTFB: %{time_starttransfer}s\n" https://seudominio.com.br/produto/camiseta-basica/
Em um VPS de 2 vCPUs, ao rodar este comando você normalmente verá o MISS na faixa de centenas de milissegundos e o HIT abaixo de 50 ms, porque o Nginx lê o arquivo do disco sem acionar PHP. Para estressar, instale o wrk ou ab e dispare conexões concorrentes contra uma categoria enquanto observa htop: com o cache ativo, o uso de CPU dos processos PHP-FPM praticamente não deve se mover. Se o backend subir junto com a carga, o bypass está pegando mais do que deveria — verifique cookies de plugins de analytics ou de consentimento que podem estar listados no map.
Com TTL de 2 minutos e proxy_cache_lock, quando a cópia expira apenas uma requisição vai ao backend; as demais aguardam ou recebem a versão stale. Esse comportamento é o que impede o efeito manada (cache stampede) no momento em que todo mundo abre a mesma página de oferta. Se a loja cresceu além do que um único servidor aguenta, vale avaliar a diferença entre hospedagem de sites e VPS para decidir onde cada camada deve rodar.
Problemas comuns e como resolver
Sintoma: produto adicionado ao carrinho não aparece ou carrinho de outro cliente é exibido
Causa: alguma rota do WooCommerce está sendo cacheada — geralmente ?wc-ajax=get_refreshed_fragments ou o cookie woocommerce_items_in_cart não foi detectado porque o map usa comparação exata em vez de regex.
Solução: confirme que as entradas do map começam com ~*, esvazie o cache com rm -rf /var/cache/nginx/woo/* e recarregue o Nginx. Teste novamente com curl enviando o cookie.
Sintoma: redirecionamento infinito ou "mixed content" após ativar o proxy
Causa: o backend recebe a requisição em HTTP na porta 8080 e o WordPress acredita que o site está sem SSL, forçando redirect para HTTPS, que volta ao proxy, que repete o ciclo.
Solução: adicione o trecho de HTTP_X_FORWARDED_PROTO no wp-config.php, mantenha proxy_set_header X-Forwarded-Proto https e remova qualquer RewriteRule de redirecionamento HTTPS do .htaccess.
Sintoma: X-Cache-Status sempre MISS, nunca HIT
Causa: o backend envia Set-Cookie ou Cache-Control: no-cache em toda resposta (plugin de sessão, PHP session_start ou tema com cookie de idioma), e o Nginx recusa gravar.
Solução: mantenha proxy_ignore_headers Cache-Control Expires Set-Cookie e identifique com curl -I http://127.0.0.1:8080/ -H "Host: seudominio.com.br" qual plugin está emitindo o cookie para visitantes anônimos; desative-o ou restrinja-o.
Sintoma: erro 502 Bad Gateway em horários de pico
Causa: o pool do PHP-FPM esgotou pm.max_children e o Apache parou de responder na 8080, ou o Nginx atingiu o limite de descritores de arquivo.
Solução: ative proxy_cache_use_stale http_502 (já presente no exemplo) para servir a cópia antiga enquanto o backend se recupera, aumente worker_rlimit_nofile e revise o dimensionamento do PHP-FPM com base na RAM disponível.
Perguntas frequentes sobre Nginx como proxy reverso com cache para WooCommerce
O cache do proxy reverso quebra o carrinho e o checkout do WooCommerce?
Quebra apenas se você cachear tudo indiscriminadamente. A configuração correta ignora o cache quando existem cookies como woocommerce_items_in_cart, woocommerce_cart_hash, wp_woocommerce_session_* e wordpress_logged_in_*, além de excluir as URLs /carrinho/, /finalizar-compra/, /minha-conta/ e /wp-admin/. Assim o visitante anônimo recebe a página cacheada e quem tem carrinho ativo passa direto ao PHP.
Qual a diferença entre proxy_cache e fastcgi_cache no Nginx para WooCommerce?
O fastcgi_cache guarda a resposta do PHP-FPM quando o próprio Nginx conversa diretamente com o PHP. O proxy_cache funciona na camada de proxy reverso, guardando respostas de um backend HTTP (Apache, outro Nginx ou container), o que permite separar a camada de cache da camada de aplicação e absorver picos antes do tráfego chegar ao WordPress. Ambos aceitam as mesmas regras de bypass por cookie e URL.
Como limpar o cache do Nginx após atualizar produtos ou preços na loja?
A forma mais simples é remover o diretório de cache com rm -rf /var/cache/nginx/woo/* e recarregar o Nginx com systemctl reload nginx, o que esvazia tudo sem derrubar conexões. Para invalidação seletiva, use um plugin de cache no WordPress compatível com purge por URL ou configure proxy_cache_bypass com um header secreto. Em picos, prefira TTLs curtos (1 a 5 minutos) em vez de limpar manualmente.
Quanto tempo de cache usar para páginas do WooCommerce em picos de acesso?
Para home, categorias e páginas de produto, um TTL entre 60 segundos e 5 minutos já reduz drasticamente a carga no PHP e no banco, pois milhares de visitantes simultâneos passam a receber a mesma cópia. Ative proxy_cache_use_stale e proxy_cache_background_update para servir conteúdo levemente desatualizado enquanto o Nginx renova a cópia em segundo plano, evitando que todos os pedidos cheguem ao backend ao mesmo tempo.
Como saber se a página está sendo servida do cache do proxy reverso?
Adicione o header add_header X-Cache-Status $upstream_cache_status no bloco server e consulte com curl -I https://seudominio.com.br/. O valor HIT indica resposta vinda do cache, MISS indica que foi buscada no backend e BYPASS mostra que uma regra de exclusão (cookie de carrinho ou URL de checkout) foi acionada. Comparar o TTFB entre HIT e MISS confirma o ganho real.
Conclusão
- Coloque o backend em 127.0.0.1:8080 e deixe o Nginx 1.28 na frente com
proxy_cache, TTL de 1 a 5 minutos eproxy_cache_lockpara evitar o efeito manada. - Trate o bypass por cookie e URL como regra de segurança, não como otimização: sem ele, carrinhos e dados de clientes podem vazar entre sessões.
- Valide HIT, MISS e BYPASS com
curle um teste de carga antes de qualquer campanha — o pico não é hora de descobrir que o cache estava desligado.
Leia também
- Como otimizar performance no Nginx para WooCommerce: 7 ajustes
- Entenda por que o WooCommerce fica lento e como corrigir
- Comparativo de cache no cPanel: acelerar WordPress sem quebrar SSL
Precisa de ajuda com Nginx e WooCommerce em picos de acesso?
Um VPS com recursos dedicados e acesso root permite separar proxy, aplicação e banco exatamente como descrito aqui, com a flexibilidade de ampliar CPU e memória antes de uma campanha. A equipe da AviraHost pode orientar o dimensionamento adequado para a sua loja.