16. Install Matomo

by Double Bastion - Updated April 19, 2026

No server that hosts websites is complete without a traffic monitoring application. The best free and open source web traffic monitoring application is Matomo (former Piwik). Matomo is an accurate and flexible web analytics application that tracks visits to websites and applications and builds detailed reports and graphs.

To install Matomo, first log in to phpMyAdmin and create a database called ‘matomodb’ (or other name of your choice) and a username called ‘matomodbuser’ (or other name that you prefer). Write down the database name, the username and the password. Give the user all the rights over the new database, except for ‘grant’.

Next, navigate to the web root directory:

cd /var/www

Create a directory for Matomo and switch to it:

mkdir matomo
cd matomo

Download the latest version of Matomo from the official website:

wget https://builds.matomo.org/matomo-latest.zip

Unzip the archive, then delete the original archive:

unzip matomo-latest.zip
rm matomo-latest.zip

Navigate to the matomo directory:

cd matomo

Copy all content to the parent directory and switch to the parent directory:

cp -r * ../
cd ..

Remove the matomo directory and the installation instructions file:

rm -rf matomo
rm 'How to install Matomo.html'

Set the right permissions for the /var/www/matomo directory:

chown -R www-data:www-data /var/www/matomo
find /var/www/matomo -type d -exec chmod 750 {} +
find /var/www/matomo -type f -exec chmod 640 {} +

To obtain a Let’s Encrypt certificate for stats.example.com, first open the /etc/nginx/sites-enabled/0-conf file:

nano /etc/nginx/sites-enabled/0-conf

Add the following lines at the end of the file, replacing example.com with your domain:

server {
   listen 80;
   listen [::]:80;
   server_name stats.example.com;

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

   location /.well-known/acme-challenge {
        root /var/www;
   }
}

Restart Nginx:

systemctl restart nginx

Next, edit your DNS settings. Add an A entry and an AAAA entry for stats.example.com. These entries are similar with the entries you already have for example.com. It’s just that instead of example.com you use stats.example.com.

When the DNS settings have propagated, which can happen rapidly, you can install the Let’s Encrypt certificate for stats.example.com by running:

certbot certonly --agree-tos --webroot -w /var/www/ -d stats.example.com

Then open the /etc/nginx/sites-enabled/0-conf file and replace the entire server block of stats.example.com with the following server block, in order to allow Nginx to serve Matomo over TLS:

server {
    listen  80;
    listen [::]:80;
    server_name stats.example.com;
    return  301 https://stats.example.com$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name stats.example.com;
    root /var/www/matomo;

    index index.php;
    port_in_redirect off;


    ssl_certificate /etc/letsencrypt/live/stats.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/stats.example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/stats.example.com/chain.pem;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;

    ssl_session_timeout 4h;
    ssl_session_cache shared:SSL:40m;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    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_stapling on;
    ssl_stapling_verify on;

    add_header Strict-Transport-Security "max-age=63072000" always;
    add_header X-Frame-Options SAMEORIGIN;
    add_header Referrer-Policy origin always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Robots-Tag "noindex, nofollow, nosnippet, noarchive";

    location /.well-known/acme-challenge {
        root /var/www;
    }

    location = /robots.txt {
        allow all;
    }

    location ~ ^/(index|matomo|piwik|js/index|plugins/HeatmapSessionRecording/configs)\.php$ {
      try_files $uri =404;
      fastcgi_split_path_info ^(.+\.php)(/.+)$;
      include fastcgi_params;
      fastcgi_index index.php;
      fastcgi_param HTTPS on;
      fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
    }

    ## deny access to all other .php files
    location ~* ^.+\.php$ {
        deny all;
        return 403;
    }

    ## serve all other files normally
    location / {
        try_files $uri $uri/ =404;
    }

    ## disable all access to the following directories
    location ~ ^/(config|tmp|core|lang) {
        deny all;
        return 403; # replace with 404 to not show these directories exist
    }

    location ~ /\.(?!well-known).* {
        deny  all;
        return 403;
    }

    location ~ /\.ht {
        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;
        ## Cache images,CSS,JS and webfonts for an hour
        ## Increasing the duration may improve the load-time, but may cause old files to show after a Matomo upgrade
        expires 1h;
        add_header Pragma public;
        add_header Cache-Control "public";
    }

    location ~ ^/(libs|vendor|plugins|misc|node_modules) {
        deny all;
        return 403;
    }

    ## properly display textfiles in root directory
    location ~/(.*\.md|LEGALNOTICE|LICENSE) {
        default_type text/plain;
    }

    access_log /var/log/sites/stats.example.com/access.log;
    error_log  /var/log/nginx/stats.example.com.error.log notice;
}

Replace example.com with your domain.

Create the directory for access logs:

mkdir -p /var/log/sites/stats.example.com

Configure logrotate to rotate Matomo’s access logs:

nano /etc/logrotate.d/nginx

Add the following block at the end of the file:

/var/log/sites/stats.example.com/access.log {
        missingok
        rotate 10
        compress
        delaycompress
        notifempty
        create 0640 www-data adm
        size 2M
        sharedscripts
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi; \
        endscript
        postrotate
                [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`
        endscript
}

Restart Nginx:

systemctl restart nginx

16.1. Configure Fail2ban to protect Matomo against brute-force attacks


First, create a custom filter for Matomo:

nano /etc/fail2ban/filter.d/matomo.conf

Add the following content inside this file:

[Definition]

failregex = ^<HOST> .* \"POST /\?module=Login HTTP/2.0\" 403 141.*$
ignoreregex =

Next, edit the /etc/fail2ban/jail.local file:

nano /etc/fail2ban/jail.local

Add the following block right above the [phpmyadmin] block:

[matomo]
enabled = true
filter = matomo
logpath = /var/log/sites/stats.example.com/access.log
port = 80,443
findtime = 3600
maxretry = 4
bantime = 604800

Replace example.com with your domain.

Reload Fail2ban:

systemctl reload fail2ban

16.2. Install Matomo using the web interface


To increase the speed of traffic data archiving, you’ll have to enable mysqli.allow_local_infile in php.ini, so as to allow Matomo to import traffic data directly into the database from a file created by itself, instead of running thousands of INSERT statements. To do this run:

nano /etc/php/8.2/fpm/php.ini

Remove the semicolon from the beginning of the ;mysqli.allow_local_infile = On directive, to make it look like this:

mysqli.allow_local_infile = On

Restart php8.2-fpm:

systemctl restart php8.2-fpm

You can now install and configure Matomo using the web interface. Open a browser and access:

https://stats.example.com

The welcome screen will look like this:

After the system check, Matomo will show the following screen:

Click ‘Next’. You will see the third screen:

In the ‘Database Server’ field enter localhost. In ‘Login’ enter the username that you set up previously for the Matomo database, in ‘Password’ enter its password, in ‘Database Name’ enter the name of the database that you have set up earlier, leave the ‘Table Prefix’ as ‘matomo_’, in ‘Adapter’ choose ‘MYSQLI’ and in ‘Database Engine’ choose ‘MariaDB’. Click ‘Next’.

After the database tables will be created, the next screen will ask for the super user credentials:

Enter the name of the super user, a secure password, repeat the password, enter an email address, then click ‘Next’.

The next screen will prompt you to set up a website:

In ‘Website name’ you can enter its domain or a short description. In ‘Website URL’ you must enter the site’s URL including the protocol, like: https://www.example.com. In ‘Website timezone’ select the city where your server is located or the closest city to that location, in ‘Ecommerce’ choose ‘Ecommerce enabled’ if the website is an e-commerce website or choose ‘Not an Ecommerce site’ otherwise. Click ‘Next’.

The next screen will display the JavaScript tracking code that you can use to track the traffic to your website with the JavaScript method. You can copy that code in a text file to use it later. The other method that doesn’t involve JavaScript is the server log analytics method. We’ll describe both methods below and explain why the method that uses the server logs is better. Click ‘Next’.

The last screen is the ‘Congratulations’ screen:

You can leave the ‘Automatically configure geolocation using a dbip database’, ‘Enable Do Not Track support’ and ‘Anonymize the last byte(s) of visitors IP addresses’ checkboxes checked. In this way Matomo will use the free IP geolocation database offered by db-ip.com to geolocate the visitors’ IPs, it will respect the visitors’ ‘Do Not Track’ option if they enabled it in their browsers, and it will anonymize their IP address by replacing with 0 the last two segments of their IPs (which is required by law in some countries, such as Germany). Then click ‘Continue to Matomo’ to sign in with your super user name and password.

After you log in for the first time, you will see the ‘Choose your tracking method’ screen:

Don’t choose anything now. Scroll down and click ‘Hide page for an hour’.

Next, edit the /var/www/matomo/config/config.ini.php file:

nano /var/www/matomo/config/config.ini.php

Add the following line in the [General] section of the file, to force SSL connections to Matomo:

force_ssl = 1

Save and exit.

16.3. Disable brute force detection


You use Fail2ban to detect brute-force attacks, in order to have all the offending IPs blocked at the server firewall level, which is more secure than to have IPs blocked at the application level. Therefore, you’ll need to disable Matomo’s brute force detection feature, which becomes unnecessary. Click on the Administration wheel in the upper right corner, then on the left bar, under ‘System’, click on ‘General settings’, scroll down to the ‘Login’ section, uncheck ‘Enable Brute Force Detection’ and click ‘Save’.

16.4. Anonymize tracking data


The next step is to make some privacy related configurations. Click the Administration wheel in the upper right corner, then, on the left sidebar, under ‘Privacy’, click ‘Anonymize data’. You should check the following options:

– Anonymize Visitors’ IP addresses

– 2 bytes

– Also use the Anonymized IP addresses when enriching visits: Yes

– Replace User ID with a pseudonim

– Anonymize Order ID (if it’s an e-commerce website)

Then, click ‘Save’ at the bottom of that section.

Next, on the same page, under ‘Regularly delete old raw data’ check ‘Regularly delete old raw data from the database’, ‘Delete logs older than (days)’: here you can enter 180 days, or a different number. Click ‘Save’.

Under ‘Delete old aggregated report data’, check ‘Regularly delete old reports from the database’. Then, under ‘Delete reports older than (months)’ enter 12 or a different number of months, check ‘Keep basic metrics …’. Then under ‘Keep all data for’ check ‘Monthly reports’ and ‘Yearly reports’. Click ‘Save’.

Under ‘Schedule old data deletion’, choose ‘month’, then click ‘Save’.

16.5. The IP geolocation database


Matomo needs an IP geolocation database in order to identify the visitors’ geographic location. Since you left the ‘Automatically configure geolocation using a dbip database’ checkbox checked during installation, Matomo automatically configured the IP geolocation database ‘IP to City Lite’ offered by db-ip.com here. You just need to check if everything is set up properly.

Click on the right upper-corner administration wheel, then in the left panel go to ‘System’ > ‘Geolocation’. Check if under ‘Location Provider’ you have the ‘DBIP / GeoIP 2 (Php)’ option selected.

Check if under ‘Setup automatic updates of geolocation databases’, in the ‘Location Database’, ‘Download URL’ field, you have https://download.db-ip.com/free/dbip-city-lite-2024-08.mmdb.gz, where 2024-08 is the current year and month. (Matomo automatically replaces the year and month in this URL when it performs the update, so that it always downloads the latest database). Under ‘Update databases every’ choose ‘month’, then click ‘Save’.

16.6. Add a new website to Matomo


During installation you have already entered the URL of a website that you want to track. To add a new website to Matomo to analyze its traffic, click on ‘All Websites’ in the uppder right corner, then click on ‘Add a new website’, then enter the domain name, or a short description, enter the full URL, choose whether the site is an e-commerce site or not, the time zone, then click ‘Save’.

16.7. Customize the Dashboard


In the ‘Visits Over Time’ dashboard widget you can hover over the ‘Metrics to plot’ and then check all the metrics that you want to appear on the graph, for example: ‘Visits’, ‘Unique visitors’, ‘Pageviews’.

Please note that you can customize the Dashboard by removing or adding any widget from/to it. To remove a widget from the Dashboard just hover over it, then click on the X sign in the upper right corner of the widget. To add a new widget click on ‘DASHBOARD’ in the upper section of the Dashboard, then under ‘Add a widget’ click on one of the available widgets. Also, if you hover over the upper section of any widget, the mouse cursor will change to a hand. This will signal that you can drag and drop that widget to any place on the dashboard.

The data plotted on the ‘Visits Over Time’ dashboard widget are not really real-time. You have to wait a few minutes until they show up on that graph. The only real-time data about vistors and page views is displayed on the ‘Visits in Real-time’ dashboard widget.

16.8. Configure Matomo to gather and analyze traffic data


Matomo can gather web traffic data to generate the traffic statistics in multiple ways but the most powerful and widely used methods are the following two:

1) analyzing the server access logs of the monitored websites.

2) using JavaScript code that has to be embeded in all web pages (similar to Google Analytics).


The other methods involve using an image tracking link, like the following:

<img src="https://stats.example.com/matomo.php?idsite=12&amp;rec=2" style="border:0" alt="" />

which has to be embedded like the JavaScript code in all web pages, or using a client script written in JavaScript, or in server side languages like PHP (https://github.com/matomo-org/matomo-php-tracker) , Python, etc. to make requests to the Matomo tracking API. These requests can also be sent to the tracking API as POST or GET requests over HTTPS.

The image tracking code is generally used in environments where JavaScript is not allowed and has some limitations as compared to the JavaScript method.

The method with the client making requests to the tracking API (which is documented here) is used in general for environments where HTML or JavaScript code is not allowed, or for specific situations, where more granular tracking is needed.

Of course, one can also use a combination of the mentioned methods, but in general it’s enough to use just one method in order to get accurate results, that would be enough for the traffic monitoring needs of a small or medium-sized company. (Please note that if you try to use for example the ‘server log analytics method’ and the ‘JavaScript method’ simultaneously, you should add two websites to Matomo with different names and the same URL, and use one method for one website and the other method for the other website. Otherwise, Matomo will record ‘double counts’ of visits, pages, etc.)

In conclusion, we’ll describe only the most widely used methods: the ‘server log analytics method’ and the ‘JavaScript method’ and we’ll explain why the first one is actually the best.

(For a comparison between methods you can read this forum post.)

Although it was extensively used in the past, today the JavaScript tracking method is no longer the best web traffic analyses method for the following reasons:

  • more and more users are using ad blockers, such as uBlock Origin, or Adblock Plus, which disable this kind of tracking by default, or when configured to do so. These ad blockers are more and more popular not only with desktop users but also with mobile users. Some estimate that around 30 % of a website’s visitors have some kind of ad blocker in place. This depends of course on the topic of the website, country, etc. but we think that the real percent of ad blockers users is really significant, it’s rapidly increasing and shouldn’t be ignored.
  • many visitors use the ‘Do Not Track’ option available in most browsers, which is enough to prevent tracking if the tracking application respects the ‘Do Not Track’ option (which it should).
  • many visitors have cookies disabled by default, or, when prompted by a website that the site uses cookies (like sites monitored with Matomo should do), they will refuse to accept cookies. Disabling cookies will also negatively impact the traffic statistics.
  • there are visitors with JavaScript totally disabled in their browsers, be they desktop or mobile browsers. There are also visitors who access the site via proxies that block JavaScript.
  • although the embedded JavaScript is asynchronous, using it to track visitors still involves an additional HTTP request for every page view. For high traffic websites and large pages, this can have a negative impact on web page loading speed.

As the official Matomo website itself mentions, using the ‘server log analytics method’ has some disadvantages over the JavaScript method, namely: the screen resolutions, browser plugins and some page titles will not be available. The tracking cookies cannot be used with this method and this will mean missing some details, such as when crediting the acquisition of a product to a link in a newsletter, etc.

We consider these drawbacks acceptable and insignificant when compared to the advantages that this method offers over the ‘JavaScript method’. The ‘server log analytics method’ is less intrusive with regard to the visitors’ personal life, and also with regard to the website’s code which should be kept as lightweight as possible. Access logs are maintained by default by any web server, so, when using the ‘server log analytics method’ you just set up Matomo to analyze these logs which are already available and which contain less personal information about the users, as compared to the data collected using the ‘JavaScript method’. The ‘server log analytics method’ can also use IP anonymisation to protect the users’ privacy and is GDPR compliant.

16.9. The ‘server log analytics method’


In order to use this method it’s necessary that the server access logs use the extended log format which includes the user agent, the referrer URL, and full URLs (including hostnames). If these details are missing from the logs, Matomo will generate less accurate reports. Nginx logs as configured in this guide already fulfill this requirement.

Once you have added a website URL to be analyzed by Matomo during setup, you can import the access log data into Matomo by running:

python3 /var/www/matomo/misc/log-analytics/import_logs.py --url=https://stats.example.com --idsite=12 --recorders=2 /var/log/sites/yourdomain.com/access.log.1

where example.com is the domain of your matomo installation, yourdomain.com is the website whose traffic you want to analyze, 12 is the website ID (which can be found by clicking on the wheel icon in the upper right corner of the screen > Websites > Manage > the ID of every website is mentioned under its name), and 2 is the number of CPU cores of the underlying server.

Please note that in order to allow Matomo to gather traffic data for each day without ‘double counting’, the access logs have to be rotated daily. This can be done by including:

daily

in the block corresponding to all the websites that you want to monitor with Matomo, from the /etc/logrotate.d/nginx file. This is different from the access logs of other applications, such as Nextcloud or Mailman, that are set to be rotated when they reach 2BM in size. Also, it’s important to note that as you can see in the /etc/crontab file, all the scripts located in the /etc/cron.daily directory, including ‘logrotate’, are run once a day at 6:25 a.m. This means that when you set a log to be rotated ‘daily’ in the /etc/logrotate.d/nginx file, it will be rotated around 6:25 a.m. every day. This is because at that moment many actions will be started and the actual rotation of the logs can happen at a few minutes after 6:25 a.m., but surely not before 6:25 a.m. This means that all the access log data has to be imported to Matomo every day before 6:25 a.m. After 6:25 a.m., the access.log.1 file will be archived, and the access.log file will become the new access.log.1 file. So, in order to avoid losing access data, the log data should be imported before the log rotation takes place, which means before 6:25 a.m. In conclusion, you can set cron jobs to import access log data preferably between 0:00 a.m. and 6:25 a.m., but in such a way that they have the time to finish before 6:25 a.m., and in such a way that they don’t run simultaneously with other cron jobs.

The next step is to get Matomo to process and archive the collected data, in order to create the traffic reports. First time you run the archiving command, it’s recommended to run it with an additional parameter, as seen below, in order to process and archive all the data available:

php /var/www/matomo/console core:archive --force-all-websites --url='https://stats.example.com'

--force-all-websites means that the script will be forced to process the traffic data for all the websites configured in Matomo.

The next time you run this command it’s not necessary to process all the traffic data again. You can run it like this:

php /var/www/matomo/console core:archive --url='https://stats.example.com'

which will process the logs from the point where they were left last time the script ran.

After you run the commands from above, the Matomo dashboard will look like this:

You can see the number of visits and unique visitors on the dashboard, from the ‘Visits in Real-time’, ‘Visits Over Time’ and ‘Visitor Map’ widgets, or by clicking on ‘Visitors’ on the dashbaord’s left panel, then clicking on ‘Overview’, ‘Visits Log’, where you can see the visit referrers, etc. Please note that after you install Matomo and configure it to use the ‘server logs analytics method’ as described above, you will see some results and graphs beginning with the next day, but only after 5 days some pages like ‘Visits Log’, ‘Real-time’, ‘Devices’, ‘Software’, ‘Times’ (under ‘Visitors’), or ‘Pages’ (under ‘Behaviour’), will be fully populated.

16.9.1. Automate log data importing and data archiving


Obviously, you cannot run the commands from above manually every time you want to see the updated traffic data, therefore, you’ll have to automate the importing of log data and its archiving, by setting up cron jobs. You can configure cron to run the mentioned commands with any frequency, but in general it’s enough to run them once an hour or once every few hours. To set up the cron jobs for this purpose run:

crontab -e

First enter the command for importing log data:

# Configure Matomo to import server access log data every day at 5:07 a.m.
7 5 * * * python3 /var/www/matomo/misc/log-analytics/import_logs.py --url=https://stats.example.com --idsite=12 --recorders=2 /var/log/sites/yourdomain.com/access.log.1 > /dev/null 2>&1

The command from above will import the log data every day at 5:07 a.m. If you have multiple websites, you will have to enter a similar line for every website. Of course, if the cron job for the first site runs at 7 minutes past 5, the cron job for the second site should run at 10 minutes past 5 or later, so as to give the first process plenty of time to finish.

It’s recommended to run the above command manually once in the terminal, to see if it finishes without errors. Also, if you notice any anomalies in the traffic reports displayed on Matomo’s web pages, you can try to manually run the above command in terminal, to see if it will cause any errors.

If you want more control when importing log data, you can learn about additional parameters that you can use with the import command here.


Next, enter the command for archiving log data, right below the lines from above.

# Configure Matomo to archive traffic data every day at 5:14 a.m.
#14 5 * * * php /var/www/matomo/console core:archive --url='https://stats.example.com' > /dev/null 2>&1

Please note that this line is commented out. This means that it should be disabled, until you decide that you need it. When enabled, this command will run the archiving script every day at 5:14 a.m. To understand when you will need it, we’ll explain in short how Matomo archiving works.

16.9.2. Matomo archiving when using the ‘server log analytics method’


To create the traffic reports, Matomo needs to process the collected data and archive it. This processing takes some time.

For websites with a few hundred visits per day, you can trigger the processing of available data simply by accessing Matomo’s pages in a browser. To trigger data processing with the browser, just leave the command mentioned above disabled, then click the Administration wheel in the upper right corner of the Matomo Dashboard, then, on the left panel, under ‘System’, click ‘General settings’. Next, under ‘Archive reports when viewed from the browser’ check that ‘Yes’ is selected and under ‘Archive reports at most every X seconds’ you can leave the default 900 seconds. With these settings in place all the available data will be processed when accessing a page on which there is a report (visitors per day, week, month, etc.), or otherwise, every 15 minutes.

For high traffic websites, with more than a few hundred visits per day, triggering data processing by accessing Matomo’s pages is not a good idea, because it can take minutes or even tens of minues. For this situation, you will need the cron job described above, so, you will have to enable the command mentioned above by removing the number sign #. In addition to that, click the Administration wheel in the upper right corner, then, on the left panel, under ‘System’, click ‘General settings’. Next, under ‘Archive reports when viewed from the browser’ check ‘No’ and under ‘Archive reports at most every X seconds’ enter 86400, which means 24 hours. Click ‘Save’.

In general, the archiving script run by the cron job will finish in less than one minute, but for websites with very high traffic, like 10,000 visits per day and above, Matomo archiving can take a few minutes.

To check that the above command runs without errors, it is recommended to run it once in the terminal to see if it finishes as it should. Therefore, run:

php /var/www/matomo/console core:archive --url='https://stats.example.com'

Please note that the command from the cron job from above runs once every day at 5:14 a.m. You should adjust this according to the number of websites whose log data you import using the log data importing commands. The idea is to set the archiving command to run after the importing of log data has finished for all websites, considering that for one website, log data importing can last a few minutes.

16.10. The ‘JavaScript method’


If, for some reason, you still want to use the ‘JavaScript method’ instead of the superior ‘server log analytics method’ described above, you can do it as explained below.

The ‘JavaScript method’ consists in inserting the JavaScript tracking code provided by Matomo into every page of the website that you want to monitor. As it’s not practical to manually insert the code into every page, the common practice is to insert it into the header.php file of the child theme that is activated in WordPress. You can of course use a plugin for inserting this code, but this would involve installing and continuously updating an additional plugin for your website, which is to be avoided. So, the most efficient way is to manually insert the tracking code into the header.php file of your WordPress child theme. We should point out that the header.php file of the child theme is nothing else than the header.php file of the parent theme, copied to the child theme’s folder, alongside the famous functions.php file. You can also insert the code into the footer.php file, but this would mean that the short visits may not be recorded for large pages, since those pages won’t have the time to fully load in a fraction of a second.

To get the tracking code provided by Matomo click on the Administration wheel in the upper right corner, then in the left panel go to ‘Websites’, click on ‘Tracking Code’, then, in the ‘JavaScript Tracking’ section, under Website, select the website that you want the tracking code for, check any options that you may want, then copy the text in the ‘JavaScript Tracking Code’ window. It will look similar to this:

<!-- Matomo -->
<script type="text/javascript">
  var _paq = window._paq || [];
  /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
  _paq.push(['trackPageView']);
  _paq.push(['enableLinkTracking']);
  (function() {
    var u="https://stats.example.com/";
    _paq.push(['setTrackerUrl', u+'matomo.php']);
    _paq.push(['setSiteId', '12']);
    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
    g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
  })();
</script>
<!-- End Matomo Code -->

where example.com will be the domain of your Matomo installation, and 12 will be the id of the website that you want to track.

The JavaScript tracking code has to be inserted right before the closing header tag, </header>, in the header.php of your child theme. Matomo will begin gathering traffic data. The next step is to archive the traffic data.

Run:

crontab -e

Enter the command for archiving data, at the bottom of the file:

# Configure Matomo to archive traffic data every hour at 14 minutes past
#14 * * * * php /var/www/matomo/console core:archive --url='https://stats.example.com' > /dev/null 2>&1

Please note that this line is commented out. This means that it should be disabled, until you decide that you need it. When enabled, the command will run the archiving script every hour at 14 minutes past. Of course, you can change this according to your preferences. The next chapter explains when you will need it.

16.10.1. Matomo archiving when using the ‘JavaScript method’


To create the traffic reports, Matomo needs to process the collected data and archive it. This processing takes some time.

For websites with a few hundred visits per day, you can trigger the processing of available data simply by accessing Matomo’s pages in a browser. To trigger data processing with the browser, just leave the command mentioned above disabled, then click the Administration wheel in the upper right corner of the Matomo Dashboard, then, on the left panel, under ‘System’, click ‘General settings’. Next, under ‘Archive reports when viewed from the browser’ check that ‘Yes’ is selected and under ‘Archive reports at most every X seconds’ you can leave the default 900 seconds. With these settings in place all the available data will be processed when accessing a page on which there is a report (visitors per day, week, month, etc.), or otherwise, every 15 minutes.

For high traffic websites, with more than a few hundred visits per day, triggering data processing by accessing Matomo’s pages is not a good idea, because it can take minutes or even tens of minues. For this situation, you will need the cron job described above, so, you will have to enable the command mentioned above by removing the number sign #. In addition to that, click the Administration wheel in the upper right corner, then, on the left panel, under ‘System’, click ‘General settings’. Next, under ‘Archive reports when viewed from the browser’ check ‘No’, and under ‘Archive reports at most every X seconds’ enter 3600, which means one hour. Click ‘Save’.

In general, the archiving script run by the cron job will finish in less than one minute, but for websites with very high traffic, like 10,000 visits per day and above, Matomo archiving can take up to 30 minutes.

To check that the above command runs without errors, it is recommended to run it once in the terminal to see if it finishes as it should. Threfore, run:

php /var/www/matomo/console core:archive --url='https://stats.example.com'

After implementing a method for collecting traffic data and after making the GeoIP configuration as described above, the Matomo dashboard will look like this:

16.11. Understanding Matomo reports


Visit: If at a moment, a visitor visits a page, this counts as a website visit. If after 30 minutes from his last page view he visits again some page, this will count as a new website visit.

Pageview: If a visitor visits any page of the website, this counts as a pageview.

Unique pageview: It is determined by the visits that include a particular page. If the page is viewed multiple times during one visit, this counts as a unique pageview. If the page is viewed multiple times during two visits, it counts as two unique pageviews.

Unique visitor: Unique visitors are determined using first party cookies stored in the visitor’s browser. If the visitor’s browser does not accept the Matomo cookie or if the visitor has blocked or deleted the cookie, Matomo tries to match the visitor to a previous visitor with the same features (IP, resolution, browser, plugins, OS, etc), and if it can’t be matched to any previous visitor it considers it a unique visitor. When the same user visits the website on two different devices, like a laptop and a mobile phone, Matomo detects that user as two unique visitors.

User: A person that can visit a website using different devices, like a laptop, a tablet, a mobile phone, etc. Visits of the same user from different devices will be detected by Matomo as visits of different unique visitors. However, if the user logs in to the website or application, a unique User ID can be set, and this will enable Matomo to count the visitor who used different devices as the same unique visitor.

16.12. Install and uninstall Matomo plugins


To install
a GPL licensed plugin in Matomo to extend its functionality, on the Dashboard, on the left panel, click on ‘Marketplace’ > ‘Browse’, then scroll down to the plugin that you want to install and click on ‘Install’, then click on ‘Activate’.

To uninstall a plugin, first click on the Administration wheel in the upper right corner, then, on the left panel under ‘System’ click on ‘Plugins’, then scroll down to the plugin that you want to uninstall, and click on “Deactivate”. Then reload the page and click the red “Uninstall” link next to that plugin. After uninstalling it, the data for the plugin will be deleted and the plugin files will also be deleted from the /var/www/matomo/plugins directory.

16.13. Upgrading Matomo


Before upgrading Matomo to a new version, it’s recommended to verify if the new version has been tested and confirmed to function well within the suite of applications described in this guide. Once we test an application and confirm that it works well, we include it on this page.

To find out if a new version of Matomo is available, click on the Administration wheel in the upper right corner, then click on the ‘CHECK FOR UPDATES’ button in the upper section of the screen. If a new version is available, the button will show: ‘NEW UPDATE: MATOMO ….’.

Before upgrading, create a backup the Matomo database by using the export feature of phpMyAdmin (after logging in to phpMyAdmin click on the Matomo database name in the left panel, then click on ‘Export’ on the upper bar, then click on ‘Go’; rename the resulting sql file by including the date in its name.), and a backup of the Matomo files:

cd /var/www
tar cf matomo_2024-08-21.tar.xz matomo

were 2024-08-21 is the date of archiving. Save the archive along with the backup of the Matomo database in a safe location.

Navigate to your Matomo root directory:

cd /var/www/matomo

Download the latest version of Matomo from the official website:

wget https://builds.matomo.org/matomo.zip

Extract the archive, delete the zip file, and move all the files from the matomo directory to the Matomo root directory, overwriting the old files with the new ones (the /var/www/matomo/config/config.ini.php file will not be overwritten):

unzip matomo.zip
rm matomo.zip
cd matomo
cp -r * ../
cd ..
rm -rf matomo

Next, although you can run the database update process in the browser, it’s recommended, especially for medium and high traffic websites, to run this process in the terminal. Before running the update command in the terminal you should turn off visitor tracking and the Matomo user interface, to ensure that the database update will be finished without concurent read/write operations, which can lead to errors. To turn off visitor tracking and the user interface, edit the /var/www/matomo/config/config.ini.php file:

nano /var/www/matomo/config/config.ini.php

Right below the [General] line add maintenance_mode = 1, like so:

[General]
maintenance_mode = 1

Also, after the [General] section and before the [PluginsInstalled] section, add the following lines:

[Tracker]
record_statistics = 0

Next, run the database update command:

php /var/www/matomo/console core:update

The database update process can last a few minutes.

After the database update has finished, don’t forget to re-enable visitor tracking and the user interface, by adding a semicolon in front of the two parameters described above, like this:

[General]
;maintenance_mode = 1
[Tracker]
;record_statistics = 0

Of course, while the visitor tracking is disabled, the websites monitored by Matomo can still receive visits. If you use the ‘server log analytics method’ to collect traffic data, you won’t lose any of those visits during database update, because all the visits will still be recorded in the access logs of that day. The data of those logs will be imported and archived by Matomo the next day, before log rotation, according to the cron job configured as described above. On the other hand, if you use the ‘JavaScript method’ to collect traffic data, in order to avoid losing traffic data during database update, when visitor tracking is disabled, you can use a plugin called ‘Queued Tracking’ as described in the ‘Option 2’ paragraph here.

You can send your questions and comments to: