Matomo para WordPress

Cuando buscas un sistema de analítica web, pero no quieres ceder los datos a Google Analytics, la opción más interesante es la de Matomo (antiguamente Piwik).

Existen dos opciones para usar Matomo con WordPress. La primera y más sencilla (pero nada óptima) es la del propio plugin de Matomo. Este plugin incluye todo el sistema y analítica en el propio sitio (por lo que sólo se podrá usar para ese sitio). Además, es una configuración poco optimizada y que si tienes más de 1.000 visitas / día suele hacer aguas.

La otra opción, en caso de tener una instalación de Matomo optimizada (que es lo que veremos a continuación) y que puede dar soporte a varios millones de visitas y a múltiples sitios web con el 100% de configuración, es la de usar un plugin que te permite conectar con el sistema y configurar el código JavaScript a tu gusto.

Instalar Matomo

Para tener un sistema muy estable, lo mejor es tener un VPS separado de cualquier instalación actual y que te permita ir ajustando los recursos según las necesidades. Además, quizá es mejor no mezclar el software de WordPress con el de Matomo para disponer de los recursos completamente libres en cada caso.

Este tutorial ha sido creado en un VPS de Clouding.io. Puedes crear tu propio VPS desde 3€/mes.

Además, tienes la posibilidad de crear tu VPS con la imagen de WordPress en un clic.

COLABORACIÓN

Uno de los objetivos que plantearemos será que esta instalación permita aceptar cualquier tipo de hostname, del estilo a analytics.example.com. Al ser un subdominio del sitio principal, todo el sistema de cookies se considerará de primeros y, aunque en los términos y condiciones de tu sitio debes informar de la retención de datos, no deberás hacer un uso ampliado de las cookies, ya que son propias del sitio.

Los recursos recomendados dependerán de las visitas que quieras contabilizar. Aproximadamente estos son los recursos más recomendables:

100.000 visitas/mes (3.000 visitas/día)

  • 1 CPU
  • 2 GB RAM
  • 50 GB SSD

1.000.000 visitas/mes (30.000 visitas/día)

  • 4 CPU
  • 8 GB RAM
  • 250 GB SSD

El tamaño del disco es muy relativo, y quizá dependerá más de cómo se archiven los datos o cuánto tiempo quieras retenerlos, por lo que quizá es mejor comenzar con poco e ir revisando según vayan siendo necesarios.

Configurando el VPS

Para esta instalación vamos a hacer uso de un servidor Ubuntu 20. Como en cualquier servidor, comenzaremos configurando algunos elementos básicos.

El primero de ellos será la hora, un elemento bastante importante en este caso.

timedatectl set-timezone 'UTC'
timedatectl set-ntp on

Posteriormente revisaremos la versión del Ubuntu y actualizaremos todo el sistema operativo.

lsb_release -a
apt -y update && apt -y upgrade && apt -y dist-upgrade && apt -y autoremove

Instalaremos herramientas básicas.

apt -y install software-properties-common curl vim zip unzip apt-transport-https

Y dejaremos activadas las actualizaciones automáticas de seguridad o muy importantes.

apt -y install unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades

Instalando MariaDB

Para la base de datos usaremos MariaDB 10.5.

curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash -s -- --mariadb-server-version="mariadb-10.5"
apt -y install mariadb-server mariadb-client

Una vez instalado, configuraremos el propio servicio. Recuerda indicarle una contraseña para el usuario de root.

mysql_secure_installation

Como configuración especial del MariaDB para Matomo, activaremos el tamaño máximo de paquetes (debido a que la recepción de información de cada visita es mayor de la que viene por defecto).

vim /etc/mysql/mariadb.conf.d/50-server.cnf

Incluyendo los siguientes datos:

[mysqld]
max_allowed_packet = 128MB

Para acabar, reiniciaremos el servicio y configuraremos que se active al reiniciar la máquina.

systemctl stop mysql.service
systemctl enable mysql.service
systemctl start mysql.service
systemctl status mysql.service

Instalando nginx

Para Matomo siempre es mejor usar un nginx que un Apache, y en este caso es lo que vamos a hacer. Así podremos optimizar qué y cuándo se ejecuta y optimizar los recursos.

add-apt-repository -y -s ppa:ondrej/nginx
apt -y install nginx nginx-extras

Una vez instalado, reiniciaremos el servicio y lo activaremos al reiniciar la máquina.

systemctl stop nginx.service
systemctl enable nginx.service
systemctl start nginx.service
systemctl status nginx.service

Instalando PHP

Aprovechando que Matomo 4 soporta la última versión de PHP, la 8.0, instalaremos únicamente esta versión.

add-apt-repository -y -s ppa:ondrej/php
apt -y install php8.0 php8.0-fpm php8.0-common php8.0-dev php8.0-cli php8.0-bcmath php8.0-curl php8.0-gd php8.0-imap php8.0-mbstring php8.0-mysql php8.0-opcache php8.0-soap php8.0-xml php8.0-zip php8.0-xdebug libgeoip-dev php-pear pkg-config imagemagick libmagickwand-dev php8.0-imagick

Una vez instalado, activaremos el inicio automático y reiniciaremos el servicio.

systemctl stop php8.0-fpm.service
systemctl enable php8.0-fpm.service
systemctl start php8.0-fpm.service
systemctl status php8.0-fpm.service

Aprovecharemos en actualizar el PEAR.

pecl channel-update pecl.php.net

Y validaremos que tenemos PHP 8.0.

php -v

Instalando Redis

Para evitar la saturación de la base de datos, configuraremos un sistema de cola que sea el que reciba los datos y que, posteriormente, se vayan incorporando en la base de datos. De esta forma, si llega un pico de tráfico, no se saturará el sistema.

apt -y update
apt -y install redis-server php8.0-redis

Como en los casos anteriores, activaremos Redis y lo reiniciaremos.

systemctl stop redis-server.service
systemctl enable redis-server.service
systemctl start redis-server.service
systemctl status redis-server.service

Instalando Certbot (Let’s Encrypt)

Para conseguir que los dominios que alojemos tengan su certificado TLS activo y funcionando, configuraremos Certbot.

snap install core && snap install --classic certbot
ln -s /snap/bin/certbot /usr/bin/certbot

Activaremos el sistema para que una vez al día revise los certificados instalados y, si hay alguno caducado, lo actualice.

crontab -e

Y añadiremos la revisión a las 06:45 UTC cada día.

45 6 * * * certbot renew

Configurando nginx

Eliminaremos las páginas por defecto del servidor y añadiremos nuestros propios contenidos.

rm /var/www/html/index.*
vim /var/www/html/index.html

Y dejaremos el contenido:

<!DOCTYPE html>
<p>Hello World!</p>

Haremos lo mismo para el robots.txt

vim /var/www/html/robots.txt

E incluiremos el contenido para que no sea indexable.

User-Agent: *
Disallow: /

Eliminaremos la configuración por defecto de nginx.

cd /etc/nginx/sites-enabled/
rm default
cd /etc/nginx/sites-available/
rm default

Y añadiremos la nuestra.

cd /etc/nginx/
rm nginx.conf
vim nginx.conf

Configuraremos nginx a nuestra manera.

user www-data;
pid /run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 65535;
include /etc/nginx/modules-enabled/*.conf;
events {
  multi_accept on;
  worker_connections 65535;
  use epoll;
}
http {
  charset utf-8;
  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;
  server_tokens off;
  more_clear_headers Server;
  log_not_found off;
  types_hash_max_size 2048;
  client_max_body_size 64m;
  keepalive_timeout 10;
  server_names_hash_bucket_size 128;
  server_names_hash_max_size 1024;
  include /etc/nginx/mime.types;
  default_type application/octet-stream;
  # logging
  access_log /var/log/nginx/access.log;
  error_log /var/log/nginx/error.log;
  # TLS
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers on;
  # gzip
  gzip on;
  gzip_vary on;
  gzip_proxied any;
  gzip_comp_level 9;
  gzip_disable "msie6";
  gzip_buffers 16 8k;
  gzip_min_length 1100;
  gzip_types application/atom+xml application/javascript application/json application/x-javascript application/xml application/xml+rss image/svg+xml text/css text/javascript text/plain text/xml;
  # more
  include /etc/nginx/conf.d/*.conf;
  include /etc/nginx/sites-enabled/*;
}

Y haremos la configuración específica para PHP 8.0 y nginx.

cd /etc/nginx/
vim wordpress_fastcgi_8_0.conf

Incluiremos la configuración a nuestra manera.

fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
fastcgi_index index.php;
fastcgi_buffers 256 16k;
fastcgi_buffer_size 128k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_hide_header X-Powered-By;
fastcgi_hide_header X-Pingback;
fastcgi_hide_header Link;
fastcgi_intercept_errors off;
fastcgi_split_path_info ^(.+.php)(/.+)$;
try_files $fastcgi_script_name =404;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PHP_ADMIN_VALUE open_basedir=$document_root/:/usr/lib/php/:/tmp/;
fastcgi_param PATH_INFO $path_info;
set $path_info $fastcgi_path_info;
include fastcgi.conf;

Y reiniciaremos nginx para aplicar la configuración.

nginx -t
systemctl restart nginx.service

Configurando PHP

Haremos varios cambios en la configuración de PHP.

cd /etc/php/8.0/fpm/
rm php.ini
vim /etc/php/8.0/fpm/php.ini

Y dejaremos un php.ini a nuestra manera.

[PHP]
engine = On
short_open_tag = Off
precision = 14
output_buffering = 4096
zlib.output_compression = Off
implicit_flush = Off
unserialize_callback_func =
serialize_precision = -1
disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
disable_classes =
zend.enable_gc = On
zend.exception_ignore_args = On
zend.exception_string_param_max_len = 0
expose_php = Off
max_execution_time = 60
max_input_time = 60
memory_limit = 256M
error_reporting = E_ALL
display_errors = Off
display_startup_errors = Off
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
html_errors = On
variables_order = "GPCS"
request_order = "GP"
register_argc_argv = Off
auto_globals_jit = On
post_max_size = 32M
auto_prepend_file =
auto_append_file =
default_mimetype = "text/html"
default_charset = "UTF-8"
doc_root =
user_dir =
enable_dl = Off
file_uploads = On
upload_max_filesize = 32M
max_file_uploads = 20
allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60
[CLI Server]
cli_server.color = On
[Date]
date.timezone = 'UTC'
[Pdo_mysql]
pdo_mysql.cache_size = 2000
pdo_mysql.default_socket=
[mail function]
SMTP = localhost
smtp_port = 25
mail.add_x_header = Off
[ODBC]
odbc.allow_persistent = On
odbc.check_persistent = On
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096
odbc.defaultbinmode = 1
[MySQLi]
mysqli.max_persistent = -1
mysqli.allow_persistent = On
mysqli.max_links = -1
mysqli.cache_size = 2000
mysqli.default_port = 3306
mysqli.default_socket =
mysqli.default_host =
mysqli.default_user =
mysqli.default_pw =
mysqli.reconnect = Off
[mysqlnd]
mysqlnd.collect_statistics = On
mysqlnd.collect_memory_statistics = Off
[bcmath]
bcmath.scale = 0
[Session]
session.save_handler = files
session.use_strict_mode = 0
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 0
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.referer_check =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.sid_length = 26
session.trans_sid_tags = "a=href,area=href,frame=src,form="
session.sid_bits_per_character = 5
[Assertion]
zend.assertions = -1
[Tidy]
tidy.clean_output = Off
[soap]
soap.wsdl_cache_enabled=1
soap.wsdl_cache_dir="/tmp"
soap.wsdl_cache_ttl=86400
soap.wsdl_cache_limit = 5
[ldap]
ldap.max_links = -1
[opcache]
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.max_wasted_percentage=15
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1

Además, optimizaremos el PHP-FPM según los recursos de la máquina. Usando el plamnteamiento previo, tenemos:

100.000 visitas/mes (3.000 visitas/día)

  • 2 GB RAM
  • 512 MB RAM reservados
pm = dynamic
pm.max_children = 12
pm.start_servers = 6
pm.min_spare_servers = 6
pm.max_spare_servers = 9
pm.max_requests = 500

1.000.000 visitas/mes (30.000 visitas/día)

  • 8 GB RAM
  • 512 MB RAM reservados
pm = dynamic
pm.max_children = 60
pm.start_servers = 30
pm.min_spare_servers = 30
pm.max_spare_servers = 45
pm.max_requests = 500

Teniendo en cuenta estos datos, configuraremos la información en el siguiente fichero de configuración de PHP.

cd /etc/php/8.0/fpm/pool.d/
rm www.conf
vim /etc/php/8.0/fpm/pool.d/www.conf

Conde incluiremos la configuración. La de este ejemplo es para una máquina con pocos recursos (1 CPU y 2 GB de RAM).

[www]
;prefix = /path/to/pools/$pool
user = www-data
group = www-data
listen = /run/php/php8.0-fpm.sock
;listen.backlog = 511
listen.owner = www-data
listen.group = www-data
;listen.mode = 0660
;listen.acl_users =
;listen.acl_groups =
;listen.allowed_clients = 127.0.0.1
; process.priority = -19
; process.dumpable = yes
pm = dynamic
pm.max_children = 12
pm.start_servers = 6
pm.min_spare_servers = 6
pm.max_spare_servers = 9
;pm.process_idle_timeout = 10s;
pm.max_requests = 500
;pm.status_path = /status
;pm.status_listen = 127.0.0.1:9001
;ping.path = /ping
;ping.response = pong
;access.log = log/$pool.access.log
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
;slowlog = log/$pool.log.slow
;request_slowlog_timeout = 0
;request_slowlog_trace_depth = 20                           
;request_terminate_timeout = 0
;request_terminate_timeout_track_finished = no
;rlimit_files = 1024
;rlimit_core = 0
;chroot =
;chdir = /var/www
;catch_workers_output = yes
;decorate_workers_output = no
;clear_env = no
;security.limit_extensions = .php .php3 .php4 .php5 .php7
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M

Una vez acabada la configuración de PHP, reiniciaremos el servicio para aplicar la configuración.

systemctl restart php8.0-fpm.service

Configurando Redis

De la misma manera que con el resto de servicios, configuraremos Redis para que sea óptimo con Matomo.

cd /etc/redis/
rm redis.conf
vim /etc/redis/redis.conf

E incluiremos la siguiente configuración.

# include /path/to/local.conf
# include /path/to/other.conf
# loadmodule /path/to/my_module.so
# loadmodule /path/to/other_module.so
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1 ::1
bind 127.0.0.1 ::1
protected-mode yes
port 6379
tcp-backlog 511
# unixsocket /var/run/redis/redis-server.sock
# unixsocketperm 700
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis/redis-server.pid
loglevel notice
logfile /var/log/redis/redis-server.log
# syslog-enabled no
# syslog-ident redis
# syslog-facility local0
databases 4
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis
# slaveof  
# masterauth 
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
# repl-ping-slave-period 10
# repl-timeout 60
repl-disable-tcp-nodelay no
# repl-backlog-size 1mb
# repl-backlog-ttl 3600
slave-priority 100
# min-slaves-to-write 3
# min-slaves-max-lag 10
# min-slaves-max-lag is set to 10.
# slave-announce-ip 5.5.5.5
# slave-announce-port 1234
# requirepass foobared
# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
# rename-command CONFIG ""
# maxclients 10000
maxmemory 256mb
# maxmemory-policy noeviction
# maxmemory-samples 5
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
slave-lazy-flush no
appendonly no
appendfilename "appendonly.aof"
# appendfsync always
appendfsync everysec
# appendfsync no
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble no
lua-time-limit 5000
# cluster-enabled yes
# cluster-config-file nodes-6379.conf
# cluster-node-timeout 15000
# cluster-slave-validity-factor 10
# cluster-migration-barrier 1
# cluster-require-full-coverage yes
# cluster-slave-no-failover no
# cluster-announce-ip 10.1.1.5
# cluster-announce-port 6379
# cluster-announce-bus-port 6380
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
#  notify-keyspace-events Elg
#  notify-keyspace-events Ex
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 10
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
# client-query-buffer-limit 1gb
# proto-max-bulk-len 512mb
hz 10
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
# lfu-log-factor 10
# lfu-decay-time 1
# activedefrag yes
# active-defrag-ignore-bytes 100mb
# active-defrag-threshold-lower 10
# active-defrag-threshold-upper 100
# active-defrag-cycle-min 25
# active-defrag-cycle-max 75

Y reiniciaremos los servicios para que se aplique la nueva configuración.

systemctl restart redis-server.service
systemctl restart php8.0-fpm.service

Creando la base de datos

Ahora que tenemos casi todo configurado, crearemos la base de datos específica para Matomo.

Entraremos en la base de datos.

mysql -p

Y configuraremos la base de datos, el usuario y contraseña. Por favor, actualiza los datos según consideres.

CREATE DATABASE matomo CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci;
GRANT ALL ON matomo.* TO 'matomo'@'localhost' IDENTIFIED BY 'contraseña';
FLUSH PRIVILEGES;

Creando el sitio web

Configuraremos el sistema para que permita acceder desde cualquier dominio que se apunte a esta IP, manteniendo la seguridad gracias a la configuración propia de Matomo.

mkdir /webs/
mkdir /webs/matomo/

Y crearemos el sitio web en el nginx.

cd /etc/nginx/sites-available/
vim matomo.conf

Para validar todo, crearemos una configuración genérica.

server {
  listen 80;
  listen [::]:80;
  server_tokens off;
  server_name _;
  root /webs/matomo;
  index index.php index.html;
  location = /favicon.ico {
    log_not_found off;
    access_log off;
  }
  location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
  }
  location ~ /.well-known {
    allow all;
  }
  location ~ /.ht {
    deny all;
  }
}

Activaremos el sitio y su configuración.

ln -s /etc/nginx/sites-available/matomo.conf /etc/nginx/sites-enabled/
nginx -t
nginx -s reload

Y crearemos el certificado TLS para el hostname principal que vayamos a usar.

certbot certonly --email example@example.com --no-eff-email --agree-tos --force-renewal --no-redirect --webroot -w /webs/matomo/ -d analytics.example.com

Y actualizaremos la configuración del nginx para dar soporte al TLS y HTTPS.

cd /etc/nginx/sites-available/
vim matomo.conf

Con la configuración de los certificados actualizada y optimizada para Matomo.

#All HTTP traffic will be sent to HTTPS
server {
  listen 80;
  listen [::]:80;
  server_name _;
  return 301 https://$host$request_uri;
  access_log off;
}
#REAL SITE
server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  # SSL
  ssl_certificate /etc/letsencrypt/live/analytics.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/analytics.example.com/privkey.pem;
  ssl_trusted_certificate /etc/letsencrypt/live/analytics.example.com/chain.pem;
  ssl_session_cache shared:le_nginx_SSL:10m;
  ssl_session_timeout 1440m;
  ssl_session_tickets off;
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers off;
  ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
  # SSL OCSP Stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 208.67.222.222 8.8.8.8 valid=300s;
  resolver_timeout 2s;
  # Security headers
  add_header Referrer-Policy "strict-origin-when-cross-origin" always;
  add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
  add_header X-Content-Type-Options "nosniff" always;
  add_header X-XSS-Protection "1; mode=block" always;
  #logs
  access_log /var/log/nginx/matomo-access.log combined buffer=64k flush=5m;
  error_log /var/log/nginx/matomo-error.log;
  #CONFIG
  server_name _;
  root /webs/matomo;
  index index.php;
  # ROOT PHP
    location ~ ^/(index|matomo|piwik|js/index|plugins/HeatmapSessionRecording/configs)\.php$ {
    include wordpress_fastcgi_8_0.conf;
  }
  location ~* ^.+\.php$ {
    deny all;
    return 403;
  }
  # HIDDEN FILES
  location ~ /.well-known {
    allow all;
  }
  location ~ /.ht {
    deny all;
    return 403;
  }
  location ~ ^/(config|tmp|core|lang) {
    deny all;
    return 403;
  }
  location ~ js/container_.*_preview\.js$ {
    expires off;
    add_header Cache-Control 'private, no-cache, no-store';
  }
  location ~ \.(gif|ico|jpg|png|svg|js|css|htm|html|mp3|mp4|wav|ogg|avi|ttf|eot|woff|woff2|json)$ {
    allow all;
    expires 1h;
    add_header Pragma public;
    add_header Cache-Control "public";
  }
  location ~ ^/(libs|vendor|plugins|misc|node_modules) {
    deny all;
    return 403;
  }
  location ~/(.*\.md|LEGALNOTICE|LICENSE) {
    default_type text/plain;
  }
  # ROOT
  location / {
    try_files $uri $uri/ =404;
  }
}

Validamos y reiniciamos nginx para dar soporte a la nueva configuración.

nginx -t
nginx -s reload

Instalando Matomo

Comenzaremos descargando el sofrwate de Matomo.

cd /webs/
wget https://builds.matomo.org/matomo-latest.zip
unzip matomo-latest.zip

Y dejaremos los permisos correctamente.

cd /webs/matomo/
chown -R www-data:www-data ./

Entraremos en el sitio web para configurar e instalar el software. Visitaremos el dominio configurado https://analytics.example.com/.

Seguiremos los pasos.

Primero validaremos que todo está bien configurado. En principio, con la configuración que hemos ido poniendo debería de permitirnos seguir sin problema.

Configuraremos la base de datos con el nombre, usuario y contraseña que hemos añadido previamente.

El sistema creará las tablas donde se almacenará la información.

Crearemos el usuario y contraseña del usuario SuperAdministrador, que tendrá acceso a todo el sistema.


Y añadiremos el primer sitio web que queramos medir.

Y, como último paso, ya podremos ir a la pantalla de login y acceder con el usuario que acabamos de crear.

Y ¡ya estamos dentro!

Configurando Matomo

Haremos algunas configuraciones previas antes de comenzar a cambiar nada en el propio panel.

Para empezar configyraremos el sistema de archivado de datos automático. Por defecto el sistema cada vez que se entra en el panel se ejecuta el archivado, y esto puede ser muy costoso en sitios con mucho tráfico, así que lo haremos automático cada 5 minutos.

vim /etc/cron.d/matomo-archive

Y configuraremos el cron. Recuerda indicar el dominio principale.

MAILTO="example@example.com"
5 * * * * www-data /usr/bin/php /webs/matomo/console core:archive --url=https://analytics.example.com/ > /dev/null

Porteriormente forzaremos al sistema a que sólo acepte peticiones por HTTPS (y así no aparecerán mensajes de error en nuestros sitios).

vim /webs/matomo/config/config.ini.php

Donde añadiremos el mensaje para forzarlo.

[General]
force_ssl = 1

Dentro del panel añadiremos algunos «plugins» gratuitos que nos ayudarán a mejorar los datos y la optimización del sistema.

Iremos a la sección: Configuración > Plataforma > Mercado. Allí activaremos los siguientes plugins.

  • Queued Tracking
  • Js Tracker Force Async
  • Tracking Spam Prevention
  • Bot Tracker

En la sección de Configuración > Sistema > Ajustes generales, configuraremos.

  • Archivar los informes cuando sean requeridos desde el navegador: No
  • Archivar informes a lo sumo cada X segundos: 3600 seconds
  • Dominios de Intercambio de recursos de origen cruzado (CORS): *

En la subsección de Configuración > Sistema > Ajustes Generales > QueuedTracking.

  • Redis host or unix socket: 127.0.0.1
  • Redis port: 6379
  • Redis database: 0
  • Queue enabled:
  • Number of queue workers: 1 (entre 1 y 16, el número de CPU del servidor)
  • Number of requests that are processed in one batch: 25
  • Process during track request:

Y para evitar robots… en Configuración > Sistema > Ajustes Generales > TrackingSpamPrevention

  • Block tracking request from Cloud:

Configurando el WordPress

Ahora que ya tenemos nuestro primer sitio, podremos configurar el plugin para la edición externa de Matomo, que es la que acabamos de instalar. Usaremos este plugin:

Al activar el plugins nos pedirá 3 datos:

  • Modo: Auto alojado (HTTP API)
  • URL: https://analytics.example.com/
  • Token: 0a1b2c34d56e78901fa2bc3d45678efa

Para conseguir el token podemos entrar en el panel de Matomo, ir a la configuración, y dentro de Personal > Seguridad podremos generar un token.

Con el token que nos genere, podremos conectar el sitio y activar la configuración.

A partir de aquí podemos hacer configuraciones según nuestro gusto.

En los ajustes Experto, validaremos que esté de la siguiente manera:

  • Activar caché:
  • Conexión HTTP a través de: cURL
  • Método HTTP: POST
  • El tiempo de conexión caducó: 2
  • Desactivar la verificación de pares SSL: No
  • Desactivar la verificación de servidor SSL: No
  • Agente de usuario: específico
  • Agente de usuario específico: WP-Piwik
  • Activar la precarga de DNS:
  • Añadir data-cfasync=false: No
  • Forzar a Matomo a usar un protocolo específico: HTTPS (SSL)

Y con esto ya podrás disfrutar de los datos en tu propio WordPress o en el panel de Matomo.


Sobre este documento

Este documento está regulado por la licencia EUPL v1.2, publicado en WP SysAdmin y creado por Javier Casares. Por favor, si utilizas este contenido en tu sitio web, tu presentación o cualquier material que distribuyas, recuerda hacer una mención a este sitio o a su autor, y teniendo que poner el material que crees bajo licencia EUPL.