Varnish com WordPress no CentOS e Ubuntu

varnish-cache

O Varnish

O Varnish é um componente que ficou extremamente popular há alguns anos, e com bons motivos. Ele é um proxy reverso que acelera bastante o carregamento de páginas. Neste post não vamos nos aprofundar no Varnish, pois ele seria conteúdo para pelo menos 1 post inteiro. Vamos mostrar como configurá-lo junto com o WordPress no CentOS/Amazon Linux e no Ubuntu, e o seu resultado sobre a velocidade das páginas.

O WordPress

wordpress_logo

O WordPress é uma plataforma de publicação, blogs e CMS extremamente popular e muito útil e fácil de usar. Seu sucesso é tão grande que ele está completando 10 anos e não há sinais de que esteja perdendo popularidade, muito pelo contrário.

Embora o WordPress seja uma ferramenta ótima, ele pode ficar lento com uma carga mais intensa e não foi feito para comportar sozinho um volume tão pesado de acessos. O ideal é termos uma arquitetura utilizando suas facilidades de publicação, mas “protegê-lo” de uma carga mais pesada.

Neste post assumiremos que ele já está instalado no seu servidor e você quer apenas acelerá-lo com o Varnish. Porém, está no forno um outro post em breve sobre uso do WordPress de forma profissional na Amazon, no qual discutiremos as boas práticas para usá-lo de forma adequada em sites valiosos para nós. Vamos assumir que você tem o WordPress rodando 1 ou mais sites no mesmo servidor na porta 80, e então o Varnish assumirá a porta 80 e seu HTTP server passará a escutar em outra porta.

Instalando e Configurando o Varnish no CentOS

sudo yum install varnish

Precisamos na sequência modificar as configurações do servidor HTTP e todos os virtual hosts para que não usem mais a porta 80, alterando todos para alguma outra porta. No meu caso eu utilizei a 18080, pois a 8080 já estava sendo utilizada.

sudo vim /etc/httpd/conf/httpd.conf

Faça a mesma coisa para todos os sites dentro de /etc/httpd/sites-available, trocando as ocorrências da porta 80 por 18080 (ou qualquer outra que você preferir):

NameVirtualHost *:18080
Listen 18080

Backup dos arquivos originais de configuração do Varnish

sudo mv /etc/varnish/default.vcl ~/varnish-default-vcl.old
sudo mv /etc/sysconfig/varnish ~/default-varnish-old

 Configurando Varnish para cachear nosso WordPress

sudo vim /etc/sysconfig/varnish

Preencher com o conteúdo abaixo.

# Configuration file for varnish
#
# /etc/init.d/varnish expects the variables $DAEMON_OPTS, $NFILES and $MEMLOCK
# to be set from this shell script fragment.
#
# Should we start varnishd at boot?  Set to "no" to disable.
START=yes
# Maximum number of open files (for ulimit -n)
NFILES=131072

# Maximum locked memory size (for ulimit -l)
# Used for locking the shared memory log in memory.  If you increase log size,
# you need to increase this number as well
MEMLOCK=82000

# Default varnish instance name is the local nodename.  Can be overridden with
# the -n switch, to have more instances on a single server.
# INSTANCE=$(uname -n) 
# This file contains 4 alternatives, please use only one.

## Alternative 1, Minimal configuration, no VCL
#
# Listen on port 6081, administration on localhost:6082, and forward to
# content server on localhost:8080.  Use a 1GB fixed-size cache file.
#
# DAEMON_OPTS="-a :6081 \
#              -T localhost:6082 \
#        -b localhost:8080 \
#        -u varnish -g varnish \
#            -S /etc/varnish/secret \
# 	     -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G"

## Alternative 2, Configuration with VCL
#
# Listen on port 6081, administration on localhost:6082, and forward to
# one content server selected by the vcl file, based on the request.  Use a 1GB
# fixed-size cache file.
#
DAEMON_OPTS="-a :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -t 120 \
             -s malloc,256m"

## Alternative 3, Advanced configuration
#
# See varnishd(1) for more information.
#
# # Main configuration file. You probably want to change it :)
# VARNISH_VCL_CONF=/etc/varnish/default.vcl
#
# # Default address and port to bind to
# # Blank address means all IPv4 and IPv6 interfaces, otherwise specify
# # a host name, an IPv4 dotted quad, or an IPv6 address in brackets.
# VARNISH_LISTEN_ADDRESS=
# VARNISH_LISTEN_PORT=6081
#
# # Telnet admin interface listen address and port
# VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
# VARNISH_ADMIN_LISTEN_PORT=6082
#
# # The minimum number of worker threads to start
# VARNISH_MIN_THREADS=1
#
# # The Maximum number of worker threads to start
# VARNISH_MAX_THREADS=1000
#
# # Idle timeout for worker threads
# VARNISH_THREAD_TIMEOUT=120
#
# # Cache file location
# VARNISH_STORAGE_FILE=/var/lib/varnish/$INSTANCE/varnish_storage.bin
#
# # Cache file size: in bytes, optionally using k / M / G / T suffix,
# # or in percentage of available disk space using the % suffix.
# VARNISH_STORAGE_SIZE=1G
#
# # File containing administration secret
# VARNISH_SECRET_FILE=/etc/varnish/secret
# 
# # Backend storage specification
# VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}"
#
# # Default TTL used when the backend does not specify one
# VARNISH_TTL=120
#
# # DAEMON_OPTS is used by the init script.  If you add or remove options, make
# # sure you update this section, too.
# DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
#              -f ${VARNISH_VCL_CONF} \
#              -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
#              -t ${VARNISH_TTL} \
#              -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \
# 	       -S ${VARNISH_SECRET_FILE} \
#              -s ${VARNISH_STORAGE}"
#
## Alternative 4, Do It Yourself
#
# DAEMON_OPTS=""
sudo vim /etc/varnish/default.vcl

Preencher com o conteúdo abaixo, só ajustando de acordo com a sua escolha de portas.

# Default backend definition.  Set this to point to your content server.
backend default {
    .host = "127.0.0.1";
    .port = "18080";
    .connect_timeout = 60s;
    .first_byte_timeout = 60s;
    .between_bytes_timeout = 60s;
    .max_connections = 800;
}

acl purge {
        "127.0.0.1";
	"localhost";
}
sub vcl_recv {
	set req.grace = 2m;

# Set X-Forwarded-For header for logging in nginx
remove req.http.X-Forwarded-For;
set    req.http.X-Forwarded-For = client.ip;

# Remove has_js and CloudFlare/Google Analytics __* cookies and statcounte is_unique
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js|is_unique)=[^;]*", "");
# Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");

# Either the admin pages or the login
if (req.url ~ "/wp-(login|admin|cron)") {
        # Don't cache, pass to backend
        return (pass);
}

# Remove the wp-settings-1 cookie
set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-1=[^;]+(; )?", "");

# Remove the wp-settings-time-1 cookie
set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-time-1=[^;]+(;)?","");

# Remove the wp test cookie
set req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=[^;]+(;)?", "");

# Static content unique to the theme can be cached (so no user uploaded images)
# The reason I don't take the wp-content/uploads is because of cache size on bigger blogs
# that would fill up with all those files getting pushed into cache
if (req.url ~ "wp-content/themes/" && req.url ~ "\.(css|js|png|gif|jp(e)?g)") {
    unset req.http.cookie;
}

# Even if no cookies are present, I don't want my "uploads" to be cached due to their potential size
if (req.url ~ "/wp-content/uploads/") {
    return (pass);
}

# any pages with captchas need to be excluded
if (req.url ~ "^/contact/" || req.url ~ "^/links/domains-for-sale/")
{
   return(pass);
}

# Check the cookies for wordpress-specific items
if (req.http.Cookie ~ "wordpress_" || req.http.Cookie ~ "comment_") {
    # A wordpress specific cookie has been set
    return (pass);
}

# allow PURGE from localhost
if (req.request == "PURGE") {
	if (!client.ip ~ purge) {
		error 405 "Not allowed.";
	}
	return (lookup);
}
# Force lookup if the request is a no-cache request from the client
if (req.http.Cache-Control ~ "no-cache") {
   return (pass);
}

# Try a cache-lookup
return (lookup);
}
sub vcl_fetch {
   #set obj.grace = 5m;
   set beresp.grace = 2m;
}
sub vcl_hit {
   if (req.request == "PURGE") {
      purge;
      error 200 "Purged.";
   }
}
sub vcl_miss {
        if (req.request == "PURGE") {
                purge;
                error 200 "Purged.";
        }
}
sudo /etc/init.d/httpd restart
sudo /etc/init.d/varnish restart

Instalando e Configurando o Varnish no Ubuntu

O processo para o Ubuntu é idêntico, só mudando os comandos e os locais dos arquivos de configuração.

sudo apt-get install varnish

Modificar as configurações do servidor HTTP e todos os virtual hosts para que não usem mais a porta 80, alterando todos para alguma outra porta (18080 no meu caso).

sudo vim /etc/apache2/ports.conf

Faça a mesma coisa para todos os sites dentro de /etc/apache2/sites-available, trocando as ocorrências da porta 80 por 18080 (ou qualquer outra que você preferir):

NameVirtualHost *:18080
Listen 18080

Backup dos arquivos originais de configuração do Varnish

sudo mv /etc/default/varnish ~/default-varnish-old
sudo mv /etc/varnish/default.vcl ~/varnish-default-vcl.old

 Configurando Varnish para cachear nosso WordPress

sudo vim /etc/default/varnish

Preencher com o conteúdo idêntico ao da seção do CentOS.
Depois disso, fazer:

sudo vim /etc/default/varnish

Preencher também de acordo com a seção idêntica do CentOS.

sudo service apache2 restart
sudo service varnish restart

Resultados do PageSpeed

Pronto, depois de configurar o Varnish para cachear as páginas do WordPress e acelerar os carregamentos, já podemos conferir o resultado disto no PageSpeed. O blog e o site da Rivendel estavam com ratings bons já, mas de vez em quando vinha uma observação sobre melhorar o tempo de resposta do servidor. Isto ficou sensivelmente melhor com o Varnish, como podemos ver abaixo.
page_speed_site
page_speed_blog
Carregamento bem rápido e rating de 92 no site e 91 no blog, e ambos muito melhor preparados para aguentar uma carga pesada de acessos. Nada mal, né? Agradeço ao Varnish 🙂

Gostou do conteúdo? Tem alguma dúvida? Entre em contato com nossos Especialistas Mandic Cloud, ficamos felizes em ajudá-lo.