Set up and run

Installing and setting up Matomo: what matters after the installation

Matomo is installed in a quarter of an hour. Whether it then measures reliably, securely and fast is decided in the hour after: archiving, HTTPS, email, privacy settings and the right plugins. Here are the ways to install and what belongs set up right afterwards.

A wizard guides you through the installation itself: system check, database, super user, first website, tracking code. What the wizard does not take care of decides the next few years: whether reports load quickly, whether Matomo sends emails, whether spam distorts the numbers and whether the instance is secure. What runs on which server and what operations involve is covered in Matomo hosting.

Before installing: the concept first

Before the first tracking code is rolled out, a few decisions belong on the table, because later changes usually only apply to new data:

  • Which websites? Each property becomes its own website in Matomo with its own time zone and currency. Otherwise new websites get UTC and US dollars.
  • Separate development and production. Test and staging environments measure into their own Matomo website so tests do not end up in the real numbers. Matomo Tag Manager has environments for this; besides Live, Dev and Staging are preset.
  • Goals, events and e-commerce: what is measured is set by the tracking concept. How events are named is covered in Event tracking.
  • Privacy settings: IP masking, retention of raw data, consent. More in Matomo and privacy.

Ways to install

Way Good for Keep in mind
ZIP package and installation wizard most own servers upload via SSH or SFTP, then the setup below
Docker container environments Docker Compose instead of a single container, archiving as a separate container
Installer in the hosting panel web hosting with Plesk, Softaculous or Installatron set up the cron job yourself; in Plesk, Matomo advises switching off ModSecurity for the Matomo domain
Matomo for WordPress small WordPress websites runs inside WordPress, more in WordPress and WooCommerce

Download the ZIP package from matomo.org, not from third parties, and upload it to the server via SSH or SFTP. The wizard checks the system, creates the tables and asks for the super user and the first website. Matomo recommends a separate database with its own database user. In the last step, it offers to set up a DB-IP geolocation database that updates monthly; without it, Matomo only guesses the country from the browser language. IP masking is switched on by default.

The official Docker image is maintained by the community under the matomo-org umbrella. Matomo recommends Docker Compose; a single container is only meant for testing. The image comes without a cron job; Matomo’s example adds a separate container for archiving. In November 2026 there are images for Matomo 5.14, none for Matomo 6 yet.

Installing from the console is something Matomo itself does not offer. Matomo recommends installs from Git only for development, not for production.

Right after installation

What comes after the installation wizard: archiving via cron, HTTPS and trusted hostnames, email via SMTP, logo, the right plugins, security and the system check.
  1. Archiving via cron. A cron job calls core:archive every hour, as the web server user; the exact line is below. Then switch off browser-triggered archiving under Administration > System > General settings and enforce this in the configuration, so segments do not trigger archiving in the browser either. Why this makes such a difference is covered in Matomo hosting.
  2. Force HTTPS. When Matomo runs over HTTPS, force_ssl = 1 enforces secure access. The wizard enters the trusted hostnames; behind a load balancer or CDN, the proxy headers belong in the configuration. In Matomo 6, both the public and the internal hostname have to be listed there.
  3. Email via SMTP. By default, Matomo sends email via PHP’s mail() function, which often ends up in spam or does not arrive at all. Under General settings > Email server settings, enter an SMTP server; ./console core:test-email checks the result. Without working email, neither reports nor alerts arrive.
  4. Upload a logo. Under General settings > Branding settings, your own logo replaces the Matomo logo in the interface and in email reports.
  5. Set up the websites. Time zone and currency per website, e-commerce switched on where there is a shop, and parameters excluded from addresses that carry sessions or personal details. Matomo removes click IDs such as gclid and fbclid by itself.
  6. System check. Under Administration > Diagnostic > System check or with ./console diagnostics:run, Matomo shows what is still missing: cron, write permissions, database, PHP settings, protected directories.

The cron job for archiving

On a Linux server, one file under /etc/cron.d/ is enough, for example /etc/cron.d/matomo-archive. It starts archiving every hour at minute five, as the web server user (www-data on Debian and Ubuntu), and writes the output to a log file:

# Matomo: archive reports every hour
5 * * * * www-data /usr/bin/php /var/www/matomo/console core:archive --matomo-domain=https://matomo.example.com > /var/log/matomo/archive.log 2>&1

Adapt the PHP and Matomo paths, the address and the user to your server; the log directory has to belong to that user. In a crontab without a user column, for example with crontab -u www-data -e, www-data drops out of the line. In Plesk it is a scheduled task, in a Docker setup a separate container.

Then switch off browser-triggered archiving. You can do this in the interface or directly in config/config.ini.php:

[General]
enable_browser_archiving_triggering = 0
browser_archiving_disabled_enforce = 1
time_before_today_archive_considered_outdated = 3600

The second line makes sure segments do not trigger archiving in the browser either. The third recalculates today’s reports at most once an hour, which Matomo recommends for medium and high traffic. The system check shows whether the cron job runs: it warns when the last run is older than one day.

Plugins that belong from the start

Alerts for outages. Without an alert, a tracking outage only comes to light when numbers are missing. Matomo’s free Custom Alerts plugin sends an email when a metric crosses a threshold. Feinwerk Sentinel checks each website’s data every hour and also reports problems in Slack or Microsoft Teams.

Set up Tracking Spam Prevention. For Matomo 5, the plugin is free in the Marketplace; in Matomo 6 it is built in and active by default. It is worth going through the settings once:

  • Block cloud provider networks, with Matomo’s maintained list.
  • Block headless browsers that identify themselves as such.
  • Limit actions per visit: by default Matomo records all of them; according to Matomo, most websites have no more than 100 to 300. An email address gets notified about blocked IP addresses.
  • Block SDKs and server-side libraries, but only if only the tracking code or the Tag Manager measures.
  • Countries and IP lists: only allow or exclude certain countries, allow or block individual networks.

This is basic protection against obvious automation, not spam protection. Bots that come with a real browser from other networks are only detected by a plugin such as Feinwerk Tracking Spam Score. More in Matomo 6.

Campaign reports: by default, Matomo only shows name and keyword for campaigns. Matomo’s free Marketing Campaigns Reporting plugin adds source, medium, content, campaign ID, group and placement, each with reports and segments, for mtm and utm parameters. It belongs in before the first campaigns, because Matomo only stores these fields once the plugin is active. How campaign links are built is covered in Campaign tracking.

For high traffic: the free QueuedTracking plugin buffers tracking requests in Redis or MySQL and writes them to the database in batches.

Security from day one

  • Two-factor authentication for all users, enforceable under General settings. It does not cover requests with an API token; how tokens stay safe is covered in API, MCP and OAuth.
  • Protected directories: for Apache, Matomo creates .htaccess files that lock config, core, lang and tmp; this needs AllowOverride All. nginx needs its own rules; both are in the next section.
  • Keep write permissions tight: files 644, directories 755, never 777. Matomo mainly needs to write to tmp.
  • Secure the sign-in: after 20 failed attempts in 60 minutes, Matomo blocks the IP address. A list of allowed IP addresses can be set in the configuration and then also applies to the API.
  • Leave plugin upload off: Matomo itself warns that uploading plugins through the interface allows third-party code to run.

More on hardening server and Matomo in the service Security and hardening.

Web server rules for Apache and nginx

Matomo sits in the web root, but not everything in it may be reachable from outside. config holds the database password, tmp holds caches and session data. Only a few files need to be reachable: the interface via index.php, tracking via matomo.php and matomo.js (plus the old names piwik.php and piwik.js) and the Tag Manager containers under js/.

Apache: Matomo creates the rules itself, as .htaccess files. They lock config, core, lang and tmp completely and let only images, scripts, styles and fonts through in libs, vendor, plugins, misc and node_modules. For Apache to read them, the directory needs AllowOverride All. If they are missing, ./console core:create-security-files creates them again. A basic virtual host, with a second lock in case an .htaccess is missing:

<VirtualHost *:80>
    ServerName matomo.example.com
    Redirect permanent / https://matomo.example.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName matomo.example.com
    DocumentRoot /var/www/matomo

    SSLEngine on
    SSLCertificateFile    /etc/letsencrypt/live/matomo.example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/matomo.example.com/privkey.pem

    <Directory /var/www/matomo>
        # Matomo ships its own .htaccess files
        AllowOverride All
        Options -Indexes
        Require all granted
    </Directory>

    # Second lock in case an .htaccess is missing
    <DirectoryMatch "^/var/www/matomo/(config|core|lang|tmp|\.git)(/|$)">
        Require all denied
    </DirectoryMatch>
</VirtualHost>

nginx does not read .htaccess files, so the rules belong in the configuration. Matomo maintains a template for this. Its core: only the PHP files Matomo needs from outside are executed, all others answer with 403, and the protected directories are locked. In shortened form:

server {
    listen 80;
    server_name matomo.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    http2 on;   # nginx 1.25.1 or later; older versions: listen 443 ssl http2;
    server_name matomo.example.com;
    root /var/www/matomo;
    index index.php;

    ssl_certificate     /etc/letsencrypt/live/matomo.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/matomo.example.com/privkey.pem;

    add_header Referrer-Policy origin always;
    add_header X-Content-Type-Options "nosniff" always;

    # Only execute these PHP files
    location ~ ^/(index|matomo|piwik|js/index|plugins/HeatmapSessionRecording/configs)\.php$ {
        include snippets/fastcgi-php.conf;
        try_files $fastcgi_script_name =404;
        fastcgi_param HTTP_PROXY "";
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;   # path to your PHP version
    }

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

    location / { try_files $uri $uri/ =404; }

    # Protected directories and hidden files
    location ~ ^/(config|tmp|core|lang) { deny all; return 403; }
    location ~ /\.(ht|git) { deny all; return 403; }

    # Do not cache Tag Manager preview containers
    location ~ js/container_.*_preview\.js$ {
        expires off;
        add_header Cache-Control 'private, no-cache, no-store';
    }

    # Allow static files, also in plugins and vendor
    location ~ \.(gif|ico|jpg|png|svg|js|css|htm|html|mp3|mp4|wav|ogg|avi|ttf|eot|woff|woff2)$ {
        allow all;
        expires 1h;
        add_header Cache-Control "public";
    }

    # The rest of these directories stays locked
    location ~ ^/(libs|vendor|plugins|misc|node_modules) { deny all; return 403; }

    # Serve text files in the root directory as text
    location ~ /(.*\.md|LEGALNOTICE|LICENSE) { default_type text/plain; }
}

Order matters: nginx checks regular-expression locations in sequence, which is why the rule allowing static files comes before the lock on plugins and vendor. Adapt TLS settings, certificates and the PHP path to your server. The system check then shows whether everything works: it requests protected files such as config/config.ini.php from outside and reports if they are reachable.

If you additionally restrict the interface to certain IP addresses, leave tracking open: matomo.php, matomo.js, the old piwik files, the containers under js/ and the opt-out page must stay reachable for all visitors.

Updates via the console

The one-click update is convenient but needs write permissions for the whole Matomo directory. For larger instances, Matomo recommends the console:

  1. Back up database and code, free space on the database server.
  2. Put the interface into maintenance mode and pause tracking: ./console config:set General.maintenance_mode=1 and Tracker.record_statistics=0.
  3. ./console core:update --yes on a single server.
  4. Clear caches, switch tracking and interface back on, look at the system check. ./console diagnostics:unexpected-files finds files that no longer belong to the release.

Plugins are updated separately, through the Marketplace or the console. What the move to Matomo 6 adds is covered in Matomo 6.

How Matomo gets off to a good start

  • Concept first Websites, environments, goals and privacy before the first code.
  • Cron from day one Reports are ready in advance, even with more traffic.
  • Email and alerts SMTP set up, outages come to light at once.
  • Hardened and current Two factors, protected directories, updates via the console.

Typical pitfalls

  • Archiving in the browser Reports get slow as traffic grows.
  • mail() instead of SMTP Reports and alerts do not arrive.
  • Tests in the real numbers Staging measures into the production website.
  • Open directories Under nginx without Matomo's rules, config can be read from outside.

Sources

As of 13 November 2026, Matomo 5.14 and 6.0.0-rc1

FAQ

Frequently asked questions

Why does Matomo show no data after installation?

Often browser-triggered archiving is switched off but no cron job is set up, so no reports are created. Other causes are ad blockers, consent that is never given, or a firewall such as ModSecurity blocking requests to matomo.php. The system check and the real-time visitors quickly show where it gets stuck.

Can I open the installer again later?

Since Matomo 5.2, the installer locks itself 72 hours after it is first accessed. If you need it afterwards, remove the installation_first_accessed entry from config.ini.php. After installation, enable_installer = 0 switches it off entirely.

Is Docker suitable for running Matomo in production?

Yes, with Docker Compose and a separate container for archiving, because the official image comes without a cron job. Matomo points out that the images are not included in its own security checks; for strict environments, build the image yourself.

One-click update or console?

For small instances, the one-click update is enough if Matomo may write to its own directory. For larger instances, Matomo recommends the console with core:update, with maintenance mode and paused tracking during the update.

Questions about your setup?

In an intro call we'll look at your situation together.

Book an intro call

Newsletter

Matomo know-how, once a month.

Practical tips on tracking, privacy settings and performance, plus notes on important Matomo updates. No spam, unsubscribe any time.