Analytics intermediate ⏱ 45-60 minutes

Matomo Analytics: Full-Featured Open Source Analytics Platform

Deploy Matomo for enterprise-grade web analytics. Complete Google Analytics replacement with heatmaps, session recordings, and A/B testing.

By Homelab Team • 2025-01-15
#analytics#matomo#docker#self-hosted#enterprise

Introduction

Matomo (formerly Piwik) is the most comprehensive open-source analytics platform available, offering enterprise-grade features that rival and often exceed Google Analytics capabilities. With 20+ years of development, 1 million+ websites tracked, and backing from organizations like the United Nations, Amnesty International, and NASA, Matomo has proven itself as the professional choice for self-hosted analytics.

Unlike lightweight alternatives, Matomo provides the complete analytics toolkit: visitor profiles, heatmaps, session recordings, form analytics, A/B testing, media analytics, and much more—all while maintaining full data ownership and privacy compliance.

What You’ll Learn:

  • Deploy Matomo with Docker Compose for production use
  • Configure comprehensive tracking including events, e-commerce, and media
  • Set up heatmaps and session recordings (with premium plugins)
  • Implement GDPR-compliant tracking with cookie consent management
  • Create custom dashboards and scheduled reports
  • Integrate with reverse proxies and optimize for performance
  • Use advanced features like funnel analysis and cohort tracking

Prerequisites:

  • Docker and Docker Compose installed (v20.10+, v2.0+)
  • Understanding of web analytics concepts
  • 2GB+ RAM recommended (4GB+ for high traffic)
  • 5GB+ free disk space (grows with traffic)
  • MySQL/MariaDB knowledge helpful but not required

Why Matomo Analytics?

The Complete Analytics Solution

While Plausible and Umami excel at simplicity, Matomo provides depth and breadth:

Enterprise Features:

  • Complete visitor journey tracking with user profiles
  • Heatmaps and session recordings for UX optimization
  • Form analytics to identify abandonment points
  • A/B testing and multivariate testing built-in
  • E-commerce tracking with product, cart, and revenue analytics
  • Media analytics for video and audio content
  • Custom dimensions and variables
  • Goal funnel visualization
  • Cohort analysis and retention reports

Professional Capabilities:

  • Multi-user management with granular permissions
  • White-label reporting for clients
  • Automated PDF report scheduling
  • Tag Manager (Google Tag Manager alternative)
  • Log analytics for importing server logs
  • API for custom integrations and automation
  • Multi-site tracking from single installation

Privacy & Compliance:

  • 100% data ownership
  • GDPR manager built-in
  • Cookie consent integration
  • IP anonymization options
  • Data retention policies
  • Right to be forgotten tools
  • Audit logs for compliance

Matomo vs. Alternatives

FeatureMatomoPlausibleUmamiGoogle Analytics
ComplexityHighLowLowHigh
Features100+10+15+80+
PrivacyExcellentExcellentExcellentPoor
Setup Time45-60min20-30min15-20min10min
Resource UseHighLowLowN/A
HeatmapsYes (paid)NoNoNo
Session RecordingYes (paid)NoNoLimited
E-commerceAdvancedBasicBasicAdvanced
User ProfilesYesNoNoYes
Mobile AppsYesNoNoYes
Plugins100+FewFewN/A

When to Choose Matomo:

  • Need comprehensive analytics with advanced features
  • Replacing Google Analytics entirely
  • E-commerce sites requiring detailed product analytics
  • Agencies serving multiple clients
  • Organizations with strict data compliance requirements
  • Want UX analysis (heatmaps, session recordings)

Understanding Matomo Architecture

System Components

Website → Matomo JS Tracker → Matomo PHP Application → MySQL Database
          (20KB script)        (API & UI)                (Analytics Data)
                                    ↓
                              File Storage (Archived Reports, Logs)

Technology Stack:

  • Frontend: JavaScript tracker with extensive customization
  • Backend: PHP application (Symfony framework)
  • Database: MySQL 5.5+ or MariaDB 10.1+ (required)
  • Web Server: Apache or Nginx with PHP-FPM
  • Caching: Redis or file-based (recommended for performance)

What Gets Tracked:

  • Page views with full URL and title
  • Events, downloads, outlinks
  • Custom dimensions (user-defined variables)
  • E-commerce transactions and product data
  • Media plays (video/audio)
  • Site search queries
  • Form interactions and submissions
  • Campaign parameters (UTM tags)

Privacy Options:

  • Configurable IP anonymization (last 1, 2, or 3 bytes)
  • Cookie consent integration
  • User opt-out mechanisms
  • Do Not Track header respect
  • Data retention policies
  • Anonymous tracking mode

Installation: Docker Compose Method

Step 1: Create Project Directory

mkdir -p ~/matomo
cd ~/matomo

Step 2: Create docker-compose.yml

Production-ready configuration with MariaDB:

version: '3.8'

services:
  matomo:
    image: matomo:5-apache
    container_name: matomo
    restart: always
    ports:
      - "8080:80"
    environment:
      - MATOMO_DATABASE_HOST=db
      - MATOMO_DATABASE_ADAPTER=mysql
      - MATOMO_DATABASE_TABLES_PREFIX=matomo_
      - MATOMO_DATABASE_USERNAME=matomo
      - MATOMO_DATABASE_PASSWORD=matomo_password
      - MATOMO_DATABASE_DBNAME=matomo
      - PHP_MEMORY_LIMIT=2048M
      - PHP_MAX_EXECUTION_TIME=300
    volumes:
      - matomo-data:/var/www/html
      - ./config:/var/www/html/config:rw
      - ./logs:/var/www/html/logs
    depends_on:
      - db
    networks:
      - matomo-network

  db:
    image: mariadb:10.11
    container_name: matomo_db
    restart: always
    command: --max-allowed-packet=256M --innodb-log-file-size=512M
    environment:
      - MYSQL_ROOT_PASSWORD=root_password_change_me
      - MYSQL_DATABASE=matomo
      - MYSQL_USER=matomo
      - MYSQL_PASSWORD=matomo_password
    volumes:
      - matomo-db:/var/lib/mysql
    networks:
      - matomo-network

  # Optional: Redis for caching (recommended for production)
  redis:
    image: redis:7-alpine
    container_name: matomo_redis
    restart: always
    volumes:
      - matomo-redis:/data
    networks:
      - matomo-network

volumes:
  matomo-data:
  matomo-db:
  matomo-redis:

networks:
  matomo-network:
    driver: bridge

Step 3: Create Required Directories

mkdir -p config logs

# Set proper permissions
chmod 755 config logs

Step 4: Start Services

# Start all containers
docker compose up -d

# Check container status
docker compose ps

# Watch initialization logs
docker compose logs -f matomo

Expected output:

matomo  | Starting Apache...
matomo  | AH00558: apache2: Could not reliably determine the server's fully qualified domain name
matomo  | [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'

Step 5: Web-Based Setup Wizard

Navigate to: http://YOUR_SERVER_IP:8080

Setup Steps:

1. Welcome Screen

  • Click “Next” to begin setup

2. System Check

  • Matomo verifies PHP extensions and permissions
  • All items should show green checkmarks
  • Click “Next”

3. Database Setup

  • Database Server: db (container name)
  • Login: matomo
  • Password: matomo_password (from docker-compose.yml)
  • Database Name: matomo
  • Table Prefix: matomo_ (default)
  • Click “Next” to create tables

4. Super User

  • Username: admin (or your choice)
  • Password: Create strong password
  • Email: [email protected]
  • Click “Next”

5. First Website

  • Website Name: My Website
  • Website URL: https://example.com
  • Timezone: Select your timezone
  • E-commerce Site: Check if applicable
  • Click “Next”

6. Tracking Code

  • Copy the JavaScript tracking code provided
  • You’ll install this later
  • Click “Next”

7. Congratulations

  • Setup complete!
  • Click “Continue to Matomo”

Step 6: Initial Configuration

Important security steps:

  1. Change default password

    • Go to Administration (gear icon) → Personal → Security
    • Change to a strong password
    • Enable two-factor authentication (recommended)
  2. Configure trusted hosts (prevents host header attacks)

    • Create config/config.ini.php if not exists
    • Add your domain:
    [General]
    trusted_hosts[] = "analytics.yourdomain.com"
    trusted_hosts[] = "YOUR_SERVER_IP"
  3. Set up archiving (for performance)

    • We’ll configure this in the Optimization section

Installing Tracking Code

Basic JavaScript Tracking

Copy the tracking code from your Matomo installation:

From Dashboard:

  1. Settings (gear icon) → Websites → Manage
  2. Click “View Tracking Code” next to your website
  3. Copy the JavaScript code

Example tracking code:

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

Installation:

HTML websites - Add before </head>:

<!DOCTYPE html>
<html>
<head>
    <title>My Website</title>
    <!-- Matomo tracking code here -->
</head>
<body>
    <!-- Your content -->
</body>
</html>

WordPress: Use official Matomo Analytics plugin:

# Install from WordPress admin or CLI
wp plugin install matomo --activate

Configure in WordPress Admin → Matomo Analytics

React/Next.js: Install package:

npm install @datapunt/matomo-tracker-react

Usage:

// _app.js or layout.js
import { MatomoProvider, createInstance } from '@datapunt/matomo-tracker-react'

const instance = createInstance({
  urlBase: 'https://analytics.yourdomain.com',
  siteId: 1,
  trackerUrl: 'https://analytics.yourdomain.com/matomo.php',
  srcUrl: 'https://analytics.yourdomain.com/matomo.js',
})

export default function App({ Component, pageProps }) {
  return (
    <MatomoProvider value={instance}>
      <Component {...pageProps} />
    </MatomoProvider>
  )
}

Vue.js: Install vue-matomo:

npm install vue-matomo
// main.js
import VueMatomo from 'vue-matomo'

app.use(VueMatomo, {
  host: 'https://analytics.yourdomain.com',
  siteId: 1,
  router: router
})

Verifying Installation

Method 1: Real-Time Widget

  1. Go to Matomo dashboard
  2. Add “Real-time Visitors” widget
  3. Visit your website
  4. Should see yourself as current visitor

Method 2: Visitor Log

  1. Go to Visitors → Visitor Log
  2. Visit your website
  3. Should see your visit appear within seconds

Method 3: Browser DevTools

  1. Visit your website
  2. Open DevTools (F12) → Network tab
  3. Look for matomo.php request (status 200)
  4. Check Response shows image pixel

Advanced Tracking Features

Event Tracking

Track specific user interactions:

JavaScript events:

// Track button clicks
document.getElementById('signup-btn').addEventListener('click', function() {
  _paq.push(['trackEvent', 'Button', 'Click', 'Signup Button']);
});

// Track downloads
_paq.push(['trackEvent', 'Download', 'PDF', 'User Guide', 1]);

// Track video plays
_paq.push(['trackEvent', 'Video', 'Play', 'Product Demo', 120]);

Event parameters:

_paq.push(['trackEvent',
  'Category',      // e.g., 'Video', 'Button', 'Form'
  'Action',        // e.g., 'Play', 'Click', 'Submit'
  'Name',          // Optional: specific name/label
  Value            // Optional: numeric value
]);

E-commerce Tracking

Add to cart:

_paq.push(['addEcommerceItem',
  'sku-123',           // Product SKU
  'Premium Plan',      // Product name
  'Subscription',      // Product category
  49.99,              // Price
  1                   // Quantity
]);
_paq.push(['trackEcommerceCartUpdate', 49.99]);

Complete purchase:

_paq.push(['addEcommerceItem',
  'sku-123',
  'Premium Plan',
  'Subscription',
  49.99,
  1
]);

_paq.push(['trackEcommerceOrder',
  'order-12345',      // Order ID
  49.99,              // Total
  45.99,              // Subtotal
  4.00,               // Tax
  0,                  // Shipping
  false               // Discount
]);

Product page view:

_paq.push(['setEcommerceView',
  'sku-123',          // Product SKU
  'Premium Plan',     // Product name
  'Subscription',     // Category
  49.99               // Price
]);
_paq.push(['trackPageView']);

Custom Dimensions

Define custom data to track:

1. Create Custom Dimension:

  • Settings → Websites → Manage → Custom Dimensions
  • Click “Configure a new Dimension”
  • Name: User Type
  • Scope: Visit
  • Active: Yes
  • Save (note the Dimension ID)

2. Track Custom Dimension:

// Set dimension before trackPageView
_paq.push(['setCustomDimension', 1, 'Premium User']);
_paq.push(['trackPageView']);

Common use cases:

// User role
_paq.push(['setCustomDimension', 1, 'Admin']);

// Subscription tier
_paq.push(['setCustomDimension', 2, 'Pro Plan']);

// AB test variant
_paq.push(['setCustomDimension', 3, 'Variant B']);

// Content author
_paq.push(['setCustomDimension', 4, 'John Doe']);

Content Tracking

Track interactions with page content:

Enable automatic content tracking:

<script>
  _paq.push(['trackPageView']);
  _paq.push(['enableLinkTracking']);
  _paq.push(['trackAllContentImpressions']); // Add this line
</script>

Mark trackable content:

<div data-track-content>
  <img src="banner.jpg" data-content-name="Summer Sale Banner" />
  <a href="/sale" data-content-target="/sale">Shop Now</a>
</div>

Form Analytics

Track form interactions (requires Form Analytics plugin - paid):

After installing plugin:

// Automatic form tracking is enabled
// Manual tracking:
_paq.push(['FormAnalytics::scanForForms']);

Forms are automatically tracked for:

  • Form views
  • Form starts (first interaction)
  • Form submissions
  • Field-level interactions
  • Time spent per field
  • Abandonment points

Goals and Conversions

Creating Goals

1. Navigate to Goals:

  • Settings → Websites → Manage
  • Click website → Goals

2. Add New Goal:

  • Click “Add a new goal”
  • Goal Name: Newsletter Signup
  • Goal Description: User subscribes to newsletter

3. Goal Trigger Options:

URL-based goal:

  • Match Type: URL
  • Pattern: Contains /thank-you
  • Revenue: Optional (e.g., 5.00 for lead value)

Event-based goal:

  • Match Type: Event
  • Category: Form
  • Action: Submit
  • Name: Newsletter Form

Manual goal:

_paq.push(['trackGoal', 1]); // Where 1 is goal ID

Funnel Definition

Define multi-step conversion paths:

Example funnel:

  1. Product page → /product/premium
  2. Add to cart → /cart
  3. Checkout → /checkout
  4. Thank you → /thank-you (goal)

Configure in goal settings:

  • Enable “Required previous steps”
  • Add each funnel step
  • View funnel visualization in Goals reports

Reverse Proxy Configuration

Nginx Configuration

# /etc/nginx/sites-available/matomo
server {
    listen 443 ssl http2;
    server_name analytics.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/analytics.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/analytics.yourdomain.com/privkey.pem;

    # Security headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    # Increase timeouts for long-running reports
    proxy_read_timeout 300s;
    proxy_connect_timeout 75s;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
    }

    # Optimize tracking endpoint
    location = /matomo.php {
        proxy_pass http://localhost:8080/matomo.php;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_buffering off;
    }

    # Cache static assets
    location ~* .(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
        proxy_pass http://localhost:8080;
        proxy_cache_valid 200 1d;
        expires 1d;
        add_header Cache-Control "public, immutable";
    }

    # Protect sensitive files
    location ~ ^/(config|tmp|lang)/ {
        deny all;
    }
}

# HTTP redirect
server {
    listen 80;
    server_name analytics.yourdomain.com;
    return 301 https://$server_name$request_uri;
}

Enable and reload:

sudo ln -s /etc/nginx/sites-available/matomo /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Caddy Configuration

# /etc/caddy/Caddyfile
analytics.yourdomain.com {
    reverse_proxy localhost:8080 {
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-Proto {scheme}
    }

    # Security headers
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
        X-Frame-Options "SAMEORIGIN"
        X-Content-Type-Options "nosniff"
    }

    # Increase timeouts
    @long_running path /index.php*
    handle @long_running {
        reverse_proxy localhost:8080 {
            timeout 5m
        }
    }
}

GDPR Compliance and Privacy

Enabling GDPR Features

1. IP Anonymization:

  • Settings → Privacy → Anonymize Visitors’ IP
  • Select: Anonymize 2 bytes (recommended)
  • This anonymizes IPs like: 192.168.xxx.xxx

2. Cookie Consent:

  • Settings → Privacy → Users opt-out
  • Enable: “Ask for consent”
  • Matomo won’t track until consent given

3. Do Not Track:

  • Settings → Privacy → Users opt-out
  • Enable: “Support Do Not Track preference”

Matomo consent methods:

Method 1: Require consent before tracking

<script>
  var _paq = window._paq = window._paq || [];
  // Require consent before tracking
  _paq.push(['requireConsent']);

  // Other tracking code...
  _paq.push(['trackPageView']);
  _paq.push(['enableLinkTracking']);

  // When user gives consent (e.g., after banner click)
  function userGaveConsent() {
    _paq.push(['setConsentGiven']);
  }
</script>

Method 2: Cookie consent with tracking

<script>
  var _paq = window._paq = window._paq || [];
  // Track without cookies until consent
  _paq.push(['requireCookieConsent']);

  _paq.push(['trackPageView']);

  // When user gives consent for cookies
  function userAcceptedCookies() {
    _paq.push(['setCookieConsentGiven']);
  }
</script>

Integration with popular consent managers:

Cookiebot:

window.addEventListener('CookiebotOnAccept', function() {
  if (Cookiebot.consent.statistics) {
    _paq.push(['setCookieConsentGiven']);
  }
});

OneTrust:

function OptanonWrapper() {
  if (OnetrustActiveGroups.indexOf('C0002') > -1) {
    _paq.push(['setCookieConsentGiven']);
  }
}

Data Retention Policies

Configure how long data is kept:

Settings → Privacy → Data Retention:

  • Delete logs older than: 180 days (recommended)
  • Delete reports older than: Keep all reports
  • Anonymize IP addresses: 2 bytes
  • Anonymize Order IDs: Enable for e-commerce
  • Anonymize User IDs: Enable

Right to Be Forgotten

Delete specific visitor data:

Manual deletion:

  1. Settings → Privacy → GDPR Tools
  2. Enter visitor ID or email
  3. Click “Delete”
  4. Confirm deletion

API-based deletion:

curl -X POST "https://analytics.yourdomain.com/index.php"   -d "module=API&method=PrivacyManager.deleteDataSubjects"   -d "visitsToDelete[]=VISITOR_ID"   -d "token_auth=YOUR_API_TOKEN"

Performance Optimization

Auto-Archiving

By default, Matomo generates reports on-demand, which can slow down the UI.

Enable cron-based archiving:

1. Disable browser-triggered archiving: Add to config/config.ini.php:

[General]
enable_browser_archiving_triggering = 0

2. Set up cron job:

# Create archiving script
cat > /root/matomo-archive.sh << 'EOF'
#!/bin/bash
docker exec matomo php /var/www/html/console core:archive --url=https://analytics.yourdomain.com > /var/log/matomo-archive.log 2>&1
EOF

chmod +x /root/matomo-archive.sh

# Add to crontab (run every hour)
crontab -e
# Add: 5 * * * * /root/matomo-archive.sh

3. Verify archiving:

# Check archive logs
tail -f /var/log/matomo-archive.log

Redis Cache Configuration

Enable Redis for better performance:

1. Uncomment Redis service in docker-compose.yml (already included above)

2. Configure Matomo to use Redis: Add to config/config.ini.php:

[Cache]
backend = chained

[ChainedCache]
backends[] = array
backends[] = redis

[RedisCache]
host = redis
port = 6379
timeout = 0.0
password = ""
database = 14

3. Restart Matomo:

docker compose restart matomo

Database Optimization

1. Optimize tables monthly:

docker exec matomo_db mysqlcheck -u matomo -pmatomo_password --optimize matomo

2. Add to cron:

# First day of month at 3 AM
0 3 1 * * docker exec matomo_db mysqlcheck -u matomo -pmatomo_password --optimize matomo

Query Optimization

For high-traffic sites, optimize query performance:

Add to config/config.ini.php:

[General]
enable_processing_unique_visitors_year = 0
enable_processing_unique_visitors_range = 0
datatable_archiving_maximum_rows_standard = 500
datatable_archiving_maximum_rows_subtable = 100

Troubleshooting Common Issues

Issue 1: Tracking Not Working

Diagnosis:

# Check Matomo logs
docker compose logs matomo | tail -50

# Test tracking endpoint
curl -I http://YOUR_SERVER:8080/matomo.php

# Check database connection
docker exec matomo php /var/www/html/console core:run-scheduled-tasks

Solutions:

  1. Verify website ID matches in tracking code
  2. Check trusted_hosts in config.ini.php
  3. Ensure matomo.php is accessible
  4. Clear browser cache and cookies
  5. Check browser console for JavaScript errors

Issue 2: Slow Dashboard Loading

Solutions:

  1. Enable auto-archiving (see Performance section)
  2. Increase PHP memory limit:
environment:
  - PHP_MEMORY_LIMIT=4096M
  1. Optimize database (see Database Optimization)
  2. Enable Redis cache
  3. Limit date range in reports

Issue 3: Database Connection Errors

Check database status:

docker compose logs db | tail -20

# Test connection
docker exec matomo_db mysql -u matomo -pmatomo_password -e "SHOW DATABASES;"

Solutions:

  1. Verify DATABASE_URL in config.ini.php
  2. Check database container is running
  3. Ensure enough disk space
  4. Review database logs for errors

Issue 4: High Memory Usage

Symptoms: Matomo container using 2GB+ RAM

Solutions:

  1. Reduce tracking frequency for high-traffic sites
  2. Enable auto-archiving to reduce real-time processing
  3. Limit concurrent reports
  4. Increase Docker memory limit:
deploy:
  resources:
    limits:
      memory: 4G

Issue 5: Reports Not Updating

Check archiving:

# Run manual archive
docker exec matomo php /var/www/html/console core:archive --force-all-websites

# Check last archive time
docker exec matomo php /var/www/html/console core:archive --force-date-last-n=1

Solutions:

  1. Verify cron archiving is running
  2. Check archive logs for errors
  3. Ensure browser archiving is disabled
  4. Run manual archive to catch up

Backup and Restore

Complete Backup Script

#!/bin/bash
# backup-matomo.sh

BACKUP_DIR="/backups/matomo"
DATE=$(date +%Y%m%d-%H%M%S)

mkdir -p "$BACKUP_DIR"

echo "Starting Matomo backup: $DATE"

# Backup MySQL database
docker exec matomo_db mysqldump -u matomo -pmatomo_password matomo | gzip > "$BACKUP_DIR/matomo-db-$DATE.sql.gz"

# Backup Matomo files (config, plugins)
docker run --rm   --volumes-from matomo   -v "$BACKUP_DIR":/backup   alpine tar czf "/backup/matomo-files-$DATE.tar.gz"   /var/www/html/config   /var/www/html/plugins

# Backup docker-compose config
cp ~/matomo/docker-compose.yml "$BACKUP_DIR/docker-compose-$DATE.yml"

# Remove backups older than 30 days
find "$BACKUP_DIR" -type f -mtime +30 -delete

echo "Backup completed: $BACKUP_DIR"
ls -lh "$BACKUP_DIR"/*$DATE*

Automate:

chmod +x backup-matomo.sh

# Daily at 2 AM
crontab -e
# Add: 0 2 * * * /root/backup-matomo.sh >> /var/log/matomo-backup.log 2>&1

Restore from Backup

# Stop services
docker compose down

# Restore database
gunzip -c /backups/matomo/matomo-db-YYYYMMDD-HHMMSS.sql.gz |   docker exec -i matomo_db mysql -u matomo -pmatomo_password matomo

# Restore files
docker run --rm   --volumes-from matomo   -v "/backups/matomo":/backup   alpine tar xzf /backup/matomo-files-YYYYMMDD-HHMMSS.tar.gz -C /

# Restart services
docker compose up -d

# Verify
docker compose logs -f matomo

Premium Features (Optional)

Matomo offers premium plugins for advanced features:

Heatmap & Session Recording

Features:

  • Visual heatmaps (click, move, scroll)
  • Session recordings with playback
  • Form analytics
  • Identify UX issues

Installation:

  1. Purchase from Matomo Marketplace
  2. Settings → Marketplace → Upload Plugin
  3. Enable in plugin settings

A/B Testing

Features:

  • Create experiments with variants
  • Statistical significance testing
  • Automatic winner detection
  • Conversion optimization

Funnel Analysis

Premium funnel features:

  • Multi-step funnel visualization
  • Segment funnels by user attributes
  • Compare funnel performance
  • Identify drop-off points

Conclusion

You now have a comprehensive, enterprise-grade analytics system that provides:

  • Complete visitor journey tracking and user profiles
  • Advanced e-commerce and conversion tracking
  • GDPR-compliant data collection with full privacy controls
  • Heatmaps and session recordings (with premium plugins)
  • Custom dimensions and event tracking
  • Multi-site management from single installation
  • Automated reporting and scheduled exports

Next Steps:

  1. Install tracking on all your websites
  2. Set up goals for key conversions
  3. Configure e-commerce tracking if applicable
  4. Enable auto-archiving for performance
  5. Explore premium plugins for advanced features
  6. Set up automated backups
  7. Configure Redis caching for large sites

Remember: Matomo is powerful but complex. Start with basic page tracking, gradually add goals and events, then explore advanced features as you become comfortable with the platform.


Additional Resources

Official:

Community:

Integrations:

Learning:


Last Updated: January 2025 Version Covered: Matomo 5.0+