Matomo for WordPress

When you are looking for a web analytics system, but do not want to transfer the data to Google Analytics, the most interesting option is that of Matomo (formerly Piwik).

There are two options for using Matomo with WordPress. The first and simplest (but not optimal) is that of Matomo’s own plugin. This plugin includes the entire system and analytics on the site itself (so it can only be used for that site). In addition, it is a little optimized configuration and that if you have more than 1,000 visits / day it usually makes water.

The other option, in case of having an optimized Matomo installation (which is what we will see below) and that can support several million visits and multiple websites with 100% configuration, is to use a plugin that allows you to connect with the system and configure the JavaScript code to your liking.

Install Matomo

This tutorial has been created on a Clouding.io VPS. You can create your own VPS from 3€/month.

In addition, you have the possibility to create your VPS with the WordPress image in one click.

PARTNERSHIP

One of the objectives that we will propose will be that this installation allows to accept any type of hostname, of the style a analytics.example.com. Being a subdomain of the main site, the entire cookie system will be considered first-party and, although in the terms and conditions of your site you must inform of the data retention, you should not make an extended use of cookies, since they are specific to the site.

Recommended resources will depend on the visits you want to count. Approximately these are the most recommended resources:

100,000 visits/month (3,000 visits/day)

  • 1 CPU
  • 2 GB RAM
  • 50 GB SSD

1,000,000 visits/month (30,000 visits/day)

  • 4 CPU
  • 8 GB RAM
  • 250 GB SSD

The size of the disk is very relative, and perhaps it will depend more on how the data is archived or how long you want to retain it, so it may be better to start small and go reviewing as necessary.

Configuring the VPS

For this installation we are going to make use of an Ubuntu 20 server. As with any server, we’ll start by configuring some basic elements.

The first of these will be the time, a rather important element in this case.

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

Later we will review the version of Ubuntu and update the entire operating system.

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

We will install basic tools.

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

And we will leave automatic or very important security updates activated.

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

Installing MariaDB

For the database we will use 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

Once installed, we will configure the service itself. Remember to provide a password for the root user.

mysql_secure_installation

As a special configuration of the MariaDB for Matomo, we will activate the maximum size of packages (because the reception of information of each visit is greater than that which comes by default).

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

Including the following data:

[mysqld]
max_allowed_packet = 128MB

To finish, we will restart the service and configure that it is activated when restarting the machine.

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

Installing nginx

For Matomo it is always better to use an nginx than an Apache, and in this case it is what we are going to do. This way we can optimize what and when it is executed and optimize resources.

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

Once installed, we will restart the service and activate it when restarting the machine.

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

Installing PHP

Taking advantage of the fact that Matomo 4 supports the latest version of PHP, 8.0, we will install only this version.

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

Once installed, we will activate the automatic startup and restart the service.

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

We will take the opportunity to update the PEAR.

pecl channel-update pecl.php.net

And we will validate that we have PHP 8.0.

php -v

Installing Redis

To avoid saturation of the database, we will configure a queue system that is the one that receives the data and that, subsequently, are incorporated into the database. This way, if a traffic spike arrives, the system will not be saturated.

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

As in the previous cases, we will activate Redis and restart it.

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

Installing Certbot (Let’s Encrypt)

To ensure that the domains we host have their TLS certificate active and working, we will configure Certbot.

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

We will activate the system so that once a day it reviews the installed certificates and, if there is an expired one, update it.

crontab -e

And we will add the revision at 06:45 UTC each day.

45 6 * * * certbot renew

Configuring nginx

We will remove the default pages from the server and add our own contents.

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

And we will leave the content:

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

We will do the same for robots.txt

vim /var/www/html/robots.txt

And we will include the content so that it is not indexable.

User-Agent: *
Disallow: /

We will remove the default nginx setting.

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

And we will add ours.

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

We will configure nginx our way.

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/*;
}

And we will do the specific configuration for PHP 8.0 and nginx.

cd /etc/nginx/
vim wordpress_fastcgi_8_0.conf

We will include the configuration in our own way.

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;

And we will restart nginx to apply the settings.

nginx -t
systemctl restart nginx.service

Configuring PHP

We will make several changes to the PHP configuration.

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

And we will leave one php.ini in our own way.

[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

In addition, we will optimize the PHP-FPM according to the resources of the machine. Using the previous plamnteamiento, we have:

100,000 visits/month (3,000 visits/day)

  • 2 GB RAM
  • 512 MB RAM reserved
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 visits/month (30,000 visits/day)

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

Taking into account this data, we will configure the information in the following PHP configuration file.

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

Conde we will include the configuration. The one in this example is for a machine with few resources (1 CPU and 2 GB of 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

Once the PHP configuration is finished, we will restart the service to apply the configuration.

systemctl restart php8.0-fpm.service

Configuring Redis

In the same way as with the rest of the services, we will configure Redis to be optimal with Matomo.

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

And we will include the following configuration.

# 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

And we will restart the services so that the new configuration is applied.

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

Creating the database

Now that we have almost everything set up, we will create the specific database for Matomo.

We will enter the database.

mysql -p

And we will configure the database, the username and password. Please update the data as you wish.

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

Creating the website

We will configure the system to allow access from any domain that is pointed to this IP, maintaining security thanks to Matomo’s own configuration.

mkdir /webs/
mkdir /webs/matomo/

And we will create the website in the nginx.

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

To validate everything, we will create a generic configuration.

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;
  }
}

We will activate the site and its settings.

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

And we will create the TLS certificate for the main hostname that we are going to use.

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

And we will update the nginx configuration to support TLS and HTTPS.

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

With the configuration of the certificates updated and optimized for 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;
  }
}

We validate and restart nginx to support the new configuration.

nginx -t
nginx -s reload

Installing Matomo

We will start by downloading the sofrwate from Matomo.

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

And we will leave the permissions correctly.

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

We will enter the website to configure and install the software. We will visit the configured https://analytics.example.com/domain.

We will follow the steps.

First we will validate that everything is well configured. In principle, with the configuration that we have been putting should allow us to continue without problem.

We will configure the database with the name, username and password that we have previously added.

The system will create the tables where the information will be stored.

We will create the username and password of the SuperAdministrator user, who will have access to the entire system.


And we will add the first website that we want to measure.

And, as a last step, we can go to the login screen and access with the user we just created.

And we’re in!

Setting up Matomo

We’ll do some presets before we start changing anything on the panel itself.

To begin with, we will configure the automatic data archiving system. By default the system every time you enter the panel the archiving is executed, and this can be very expensive in sites with a lot of traffic, so we will do it automatically every 5 minutes.

vim /etc/cron.d/matomo-archive

And we will configure the cron. Remember to indicate the primary domain.

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

We will therefore force the system to only accept requests over HTTPS (and thus no error messages will appear on our sites).

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

Where we will add the message to force it.

[General]
force_ssl = 1

Within the panel we will add some free “plugins” that will help us improve the data and the optimization of the system.

We will go to the section: Configuración > Plataforma > Mercado. There we will activate the following plugins.

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

In the section of Configuración > Sistema > Ajustes generales, we will configure.

  • Archive reports when required from the browser: No
  • Archive reports at most every X seconds: 3600 seconds
  • Cross-Origin Resource Exchange (CORS) domains: *

In the subsection of 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 (between 1 and 16, the number of CPU of the server)
  • Number of requests that are processed in one batch: 25
  • Process during track request:

And to avoid robots… in Configuración > Sistema > Ajustes Generales > TrackingSpamPrevention

  • Block tracking request from Cloud:

Setting up WordPress

Now that we have our first site, we can configure the plugin for the external edition of Matomo, which is the one we have just installed. We will use this plugin:

When activating the plugins it will ask us for 3 data:

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

To get the token we can enter the Matomo panel, go to the configuration, and within Personal > Seguridad we can generate a token.

With the token that generates us, we can connect the site and activate the configuration.

From here we can make configurations according to our taste.

In the settings Experto, we will validate that it is as follows:

  • Enable Cache:
  • HTTP connection via: cURL
  • HTTP Method: POST
  • Connection time expired: 2
  • Disable SSL peer verification: No
  • Turn off SSL server verification: No
  • User Agent: específico
  • Specific user agent: WP-Piwik
  • Turn on DNS preloading:
  • Add data-cfasync=false: No
  • Force Matomo to use a specific protocol: HTTPS (SSL)

And with this you can already enjoy the data in your own WordPress or in the Matomo panel.


About this document

This document is regulated by the EUPL v1.2 license, published in WP SysAdmin and created by Javier Casares. Please, if you use this content in your website, your presentation or any material you distribute, remember to mention this site or its author, and having to put the material you create under EUPL license.