Technology Encyclopedia Home >How to Install Matomo Analytics on a VPS — Privacy-First Web Analytics You Control

How to Install Matomo Analytics on a VPS — Privacy-First Web Analytics You Control

I put a Google Analytics tag on sites for years without thinking much about it. Then GDPR happened, and I found myself having to add cookie consent banners, update privacy policies, and explain to clients why visitor data was going to a third party.

Matomo changed the equation. Self-hosted Matomo gives you the same analytics — visitor counts, sessions, page views, conversion goals, heatmaps — with data that stays on your own server. No cookie consent banner required by default, no third-party data access, and no concerns about data leaving your infrastructure.

Fastest path for Lighthouse users: Lighthouse has a pre-built Matomo application image — select it at instance creation and Matomo is fully installed and ready to configure in under 10 minutes. This guide covers both the image path and the manual installation for those who want custom configuration.

I run Matomo on Tencent Cloud Lighthouse. The Matomo application image is the recommended starting point — the entire stack (Nginx + PHP + MySQL + Matomo) is pre-configured when the server provisions. For analytics specifically, Lighthouse's data sovereignty advantage is important: visitor data never leaves your server infrastructure. The CBS cloud disk expansion handles Matomo's growing database as you track more sites and events, and fixed monthly bandwidth pricing means tracking high-traffic sites doesn't add variable costs.


Table of Contents

  1. Why Self-Host Analytics?
  2. Prerequisites
  3. Part 1 — Server Setup
  4. Part 2 — Create Database
  5. Part 3 — Download and Configure Matomo
  6. Part 4 — Configure Nginx
  7. Part 5 — Run the Web Installer
  8. Part 6 — Enable HTTPS
  9. Part 7 — Add the Tracking Code to Your Site
  10. Part 8 — Configure Archiving (Cron)
  11. Part 9 — Performance Optimization
  12. The Gotcha: Archiving Must Run via Cron
  13. Common Matomo Tasks

  • Key Takeaways
  • Use the appropriate Lighthouse application image to skip manual installation steps where available
  • Lighthouse snapshots provide one-click full-server backup before major changes
  • OrcaTerm browser terminal lets you manage the server from any device
  • CBS cloud disk expansion handles growing storage needs without server migration
  • Console-level firewall + UFW = two independent protection layers

Why Self-Host Analytics? {#why}

Self-hosting Matomo gives you:

  • 100% data ownership — no third party processes your visitor data
  • No sampling — all data is tracked, not sampled
  • GDPR/CCPA compliance — data stays in your jurisdiction
  • No ad blockers blocking it — since it's your own domain
  • Full raw data access — export, query, and analyze however you want
  • No per-site or per-pageview fees — track unlimited sites

Prerequisites {#prerequisites}

Requirement Notes
Cloud server Tencent Cloud Lighthouse — select Matomo application image for instant setup
PHP 7.4+ Pre-installed with the Matomo image
MySQL 5.7+ Pre-installed with the Matomo image
2 GB+ RAM More RAM = faster report generation

Part 1 — Server Setup {#part-1}

Option A — Matomo Application Image (Recommended)

  1. Go to Lighthouse → New Instance → click Application Images → select Matomo
  2. Choose the 2 vCPU / 2 GB RAM plan (sufficient for most sites) and your preferred region
  3. Click Create — the server provisions in under 2 minutes

When ready, open the Lighthouse console → Application Management on the instance:

  • You'll see the Matomo URL, database credentials, and admin information
  • Navigate to the Matomo URL and complete the installation wizard
  • Add your first website in the wizard and copy the tracking code

Done — skip to Part 3 — Matomo Configuration. The manual installation below is only needed if you're adding Matomo to an existing server or need custom PHP configuration.


Option B — Manual Installation on Ubuntu 22.04

ssh ubuntu@YOUR_SERVER_IP
sudo apt update && sudo apt upgrade -y

sudo add-apt-repository ppa:ondrej/php -y && sudo apt update

sudo apt install -y nginx php8.2-fpm php8.2-mysql php8.2-xml \
  php8.2-gd php8.2-curl php8.2-mbstring php8.2-zip \
  php8.2-cli php8.2-intl php8.2-opcache \
  mysql-server unzip wget

sudo ufw allow ssh
sudo ufw allow 'Nginx Full'
sudo ufw enable

sudo systemctl start mysql && sudo systemctl enable mysql
sudo mysql_secure_installation

Part 2 — Create Database {#part-2}

sudo mysql
CREATE DATABASE matomo_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'matomo_user'@'localhost' IDENTIFIED BY 'strong_password_here';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX, CREATE TEMPORARY TABLES
    ON matomo_db.* TO 'matomo_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Part 3 — Download and Configure Matomo {#part-3}

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

sudo mv matomo /var/www/matomo
sudo chown -R www-data:www-data /var/www/matomo
sudo find /var/www/matomo -type d -exec chmod 755 {} \;
sudo find /var/www/matomo -type f -exec chmod 644 {} \;
sudo chmod 777 /var/www/matomo/tmp
sudo chmod 777 /var/www/matomo/config

Part 4 — Configure Nginx {#part-4}

sudo nano /etc/nginx/sites-available/matomo
server {
    listen 80;
    server_name analytics.yourdomain.com;

    root /var/www/matomo;
    index index.php;

    access_log /var/log/nginx/matomo_access.log;
    error_log  /var/log/nginx/matomo_error.log;

    # Matomo tracking API
    location ~ ^/(index|matomo|piwik|js/index|plugins/HeatmapSessionRecording/configs)\.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # Deny access to PHP files in subdirectories
    location ~* ^.+\.php$ {
        deny all;
    }

    # Static files
    location / {
        try_files $uri $uri/ =404;
    }

    # Protect config directory
    location ~ ^/config/config\.ini\.php$ {
        return 403;
    }

    # Gzip
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;
}
sudo ln -s /etc/nginx/sites-available/matomo /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Part 5 — Run the Web Installer {#part-5}

Visit http://analytics.yourdomain.com. The Matomo setup wizard runs:

  1. System check — verify all PHP extensions are installed
  2. Database setup:
    • Login: matomo_user
    • Password: your password
    • Database: matomo_db
    • Table prefix: matomo_
  3. Super user — create your admin account
  4. Add website — enter the site name and URL you want to track
  5. JavaScript tracking code — note the code snippet (you'll add it to your site)

Part 6 — Enable HTTPS {#part-6}

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d analytics.yourdomain.com

After HTTPS is enabled, update the Matomo config:

In Matomo admin: System → General Settings → Force SSL/HTTPS → Enable.


Part 7 — Add the Tracking Code to Your Site {#part-7}

Matomo generates a JavaScript tracking snippet. Add it to every page you want to track:

<!-- Matomo -->
<script>
  var _paq = window._paq = window._paq || [];
  _paq.push(['trackPageView']);
  _paq.push(['enableLinkTracking']);
  (function() {
    var u="https://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 -->

Place this just before the closing </head> tag on every page.

For WordPress: Install the WP-Matomo plugin. Enter your Matomo URL and authentication token.

For Next.js:

// pages/_document.js or app/layout.tsx
<Script
  strategy="afterInteractive"
  src="https://analytics.yourdomain.com/matomo.js"
/>

Part 8 — Configure Archiving (Cron) {#part-8}

Matomo processes raw tracking data into reports via an archiving process. For high-traffic sites, configure this to run via cron instead of on-demand:

In Matomo admin: System → General Settings → Archive Reports:

  • Enable: Never trigger archiving from the browser

Then set up cron:

# Edit crontab as www-data user
sudo crontab -u www-data -e

# Add:
5 * * * * /usr/bin/php /var/www/matomo/console core:archive --url=https://analytics.yourdomain.com > /var/log/matomo-archive.log 2>&1

This runs archiving every hour at 5 minutes past. Adjust frequency based on traffic volume.


Part 9 — Performance Optimization {#part-9}

Enable file-based caching

In Matomo admin: System → General Settings → Performance:

  • Enable: Use filesystem caching

Configure PHP OPcache

sudo nano /etc/php/8.2/fpm/conf.d/10-opcache.ini
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60
sudo systemctl restart php8.2-fpm

MySQL configuration

Add to MySQL config for better performance with Matomo's write-heavy workload:

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
innodb_buffer_pool_size = 512M
innodb_flush_log_at_trx_commit = 2
innodb_log_file_size = 128M

The Gotcha: Archiving Must Run via Cron {#gotcha}

By default, Matomo archives reports when someone views the dashboard — which means the first load after a quiet period can be very slow (30+ seconds) for high-traffic sites.

The fix: disable browser-triggered archiving and configure cron archiving instead (see Part 8). This pre-builds reports on a schedule so dashboard loads are fast.

Signs you need cron archiving:

  • Dashboard loading takes more than 10 seconds
  • Reports show "This report was not generated because there was not enough archived data yet"
  • High CPU spikes when loading the dashboard

Common Matomo Tasks {#tasks}

# Run archiving manually
sudo -u www-data php /var/www/matomo/console core:archive --url=https://analytics.yourdomain.com

# Check for updates
sudo -u www-data php /var/www/matomo/console core:update

# Purge old logs (free up disk space)
sudo -u www-data php /var/www/matomo/console privacy:purge-data-subjects

# Export visits to CSV
# Via Matomo admin: Reports → Export

# View database size
mysql -u matomo_user -p -e "
SELECT table_name,
       ROUND(data_length/1024/1024, 2) AS data_mb
FROM information_schema.tables
WHERE table_schema = 'matomo_db'
ORDER BY data_length DESC LIMIT 10;"

Troubleshooting {#troubleshooting}

Issue Likely Cause Fix
Connection refused Service not running or wrong port Check systemctl status SERVICE and verify firewall rules
Permission denied Wrong file ownership or permissions Check file ownership with ls -la and use chown/chmod to fix
502 Bad Gateway Backend service not running Restart the backend service; check logs with journalctl -u SERVICE
SSL certificate error Certificate expired or domain mismatch Run sudo certbot renew and verify domain DNS points to server IP
Service not starting Config error or missing dependency Check logs with journalctl -u SERVICE -n 50 for specific error
Out of disk space Logs or data accumulation Run df -h to identify usage; clean logs or attach CBS storage
High memory usage Too many processes or memory leak Check with htop; consider upgrading instance plan if consistently high
Firewall blocking traffic Port not open in UFW or Lighthouse console Open port in Lighthouse console firewall AND sudo ufw allow PORT

Frequently Asked Questions {#faq}

Is self-hosted Matomo GDPR compliant?
Self-hosted Matomo can be configured to be GDPR compliant — no data leaves your server, and many configurations don't require cookie consent banners because no personally identifiable data is collected.

How accurate is self-hosted analytics compared to other services?
Self-hosted analytics that serves tracking scripts from your own domain (avoiding ad blocker detection) often measures more accurately than third-party scripts that are commonly blocked.

How do I add tracking to multiple websites?
Most self-hosted analytics tools support multiple sites from a single installation. Add each site in the admin panel and get a separate tracking code for each.

How much server resource does Matomo need?
Analytics databases grow over time. The 2 vCPU / 4 GB RAM plan handles millions of monthly pageviews. Use CBS cloud disk expansion as the database grows.

Can I import historical data from Google Analytics?
Most analytics tools have import functionality for Google Analytics data. Check the tool's documentation for the specific import format and process.

Deploy your private analytics today:
👉 Tencent Cloud Lighthouse — PHP-ready Ubuntu VPS
👉 View current pricing and promotions
👉 Explore all active deals and offers