Back to blog
Blog

Deploy Matomo on a VPS With Nginx and MariaDB

Deploy Matomo on a VPS with Nginx, MariaDB, HTTPS, backups, and safe updates for reliable self-hosted web analytics.

By Anurag Singh
Updated on Nov 09, 2026
Category: Blog
Share article
Deploy Matomo on a VPS With Nginx and MariaDB

Matomo is what you reach for when you’re done negotiating with hosted analytics. You want the data on infrastructure you control.

If you need funnels, goals, campaign tracking, and privacy-first settings—without handing raw traffic data to a third party—you can deploy Matomo on a VPS and keep the entire analytics stack inside your own account.

This is an open-source spotlight, not a “copy/paste 47 commands” lab. You’ll still get real deployment guidance: Docker Compose, Nginx + HTTPS, MariaDB sizing, backups, and updates.

The goal is to help you make the operational calls that matter before you put analytics in production.

Why Matomo fits teams moving off Google Analytics

Google Analytics works until it doesn’t. Retention limits, sampling in some reporting paths, and compliance reviews can turn every tracking change into a meeting.

Matomo gives you a full analytics suite that runs under your control. That usually makes governance and access rules simpler.

Matomo is open source (GPLv3). That means you can run it and modify it.

It also means you should keep custom changes small. Otherwise, upgrades can turn into an annual project.

  • Who it’s for: product teams, agencies, SaaS operators, and e-commerce sites that need detailed reporting and ownership of raw analytics data.
  • Who should choose something smaller: hobby sites or single-page marketing sites that only need basic pageviews and referrers.

Hosted analytics vs self-hosted Matomo: the real tradeoffs

Self-hosting isn’t “free.” You trade subscription fees for server ownership and ongoing maintenance.

The payoff is control. You decide retention, encryption, access, and where the data physically sits.

Decision pointHosted/proprietary analyticsMatomo on your VPS
Data ownershipVendor-controlled pipelineYou control DB + logs + exports
ComplianceDepends on vendor terms + regionDepends on your server location + policies
Cost modelMonthly per event/site/userPredictable VPS + storage costs
PerformanceVendor scales itYou size CPU/RAM/IO for peak traffic
Operational workLowBackups, updates, monitoring, hardening

Plan your VPS resources before you deploy Matomo on a VPS

Matomo’s “feel” is mostly database IO. Tracking requests are small, but writes add up quickly.

Archiving (turning raw visits into reports) is where CPU and memory usage can jump.

Use this as a practical baseline for 2026 deployments:

  • Small site (up to ~100k pageviews/month): 2 vCPU, 2–4 GB RAM, NVMe storage, 30–60 GB disk.
  • Growing site (100k–1M pageviews/month): 2–4 vCPU, 4–8 GB RAM, NVMe strongly recommended, 80–200 GB disk.
  • High traffic (multi-site, millions of pageviews/month): 4–8 vCPU, 8–16 GB RAM, tuned MariaDB, separate DB volume, and a real backup strategy.

If you already run WordPress, WooCommerce, or multiple apps on the same box, don’t stack analytics on top. You don’t want report generation competing with checkout traffic.

A dedicated analytics VPS creates a clean boundary.

For production, start with a HostMyCode VPS with NVMe storage. If you’d rather not own patching, OS hardening, and performance tuning, managed VPS hosting is often the calmer path.

That matters for analytics that gets questioned every Monday morning.

Architecture that stays boring: Docker Compose + Nginx + MariaDB

You can run Matomo directly on the host. Docker Compose usually makes upgrades, rollbacks, and migrations easier to reason about.

The common layout looks like this:

  • Matomo (PHP-FPM or Apache container) for the application
  • MariaDB for storage
  • Nginx on the host as a reverse proxy handling HTTPS and headers

You can also run Nginx in Docker. Host-level Nginx is often simpler when you already proxy several services.

It also helps when you share certificates or want consistent access/error logging in one place.

Matomo vs “lightweight” self-hosted analytics

If you’re weighing Matomo against smaller tools, the split is straightforward:

  • Matomo: deep reports, goals, funnels, segmentation, multi-site management, and a large plugin ecosystem. Heavier footprint.
  • Umami/Plausible-style tools: simpler dashboards, lighter DB load, and less operational overhead. Fewer reporting dimensions.

Pick Matomo when stakeholders need answers like “which campaign drove signups that later converted to paid users,” without exporting half your data into a BI pipeline.

Deploy Matomo on a VPS: Compose layout you can live with

Assume Ubuntu or Debian, Docker + Docker Compose plugin installed, and a DNS A/AAAA record like analytics.example.com pointing at the VPS.

A clean directory layout:

  • /opt/matomo/compose.yml
  • /opt/matomo/.env (DB passwords, salts)
  • /opt/matomo/data/ (Matomo config + plugins + uploads)
  • /opt/matomo/db/ (MariaDB volume)

Example compose.yml (trimmed to what you’ll actually maintain):

services:
  db:
    image: mariadb:11
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    environment:
      MARIADB_DATABASE: matomo
      MARIADB_USER: matomo
      MARIADB_PASSWORD: ${MARIADB_PASSWORD}
      MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
    volumes:
      - ./db:/var/lib/mysql
    restart: unless-stopped

  matomo:
    image: matomo:latest
    environment:
      MATOMO_DATABASE_HOST: db
      MATOMO_DATABASE_ADAPTER: mysql
      MATOMO_DATABASE_TABLES_PREFIX: matomo_
      MATOMO_DATABASE_USERNAME: matomo
      MATOMO_DATABASE_PASSWORD: ${MARIADB_PASSWORD}
      MATOMO_DATABASE_DBNAME: matomo
    volumes:
      - ./data:/var/www/html
    depends_on:
      - db
    restart: unless-stopped

Two operational notes that save you trouble later:

  • Pin versions once stable. “latest” is fine for evaluation. For production, switch to explicit tags after your first successful upgrade cycle.
  • Keep DB and app volumes on fast storage. Analytics writes punish slow disks. NVMe is not optional on busy sites.

Nginx reverse proxy with HTTPS (and the headers you actually want)

Put Matomo behind Nginx and Let’s Encrypt. If you already use Caddy for TLS automation, that’s fine too.

With Nginx, the server block should do the essentials. Terminate HTTPS, pass the real client IP, keep tracking endpoints working, and set sensible security headers.

Typical Nginx site file:

  • Ubuntu/Debian: /etc/nginx/sites-available/analytics.example.com → symlink into sites-enabled

Example config (assumes Matomo container exposed on localhost port 8080 via an internal Docker network or a published port):

server {
  listen 80;
  server_name analytics.example.com;

  location /.well-known/acme-challenge/ { root /var/www/letsencrypt; }
  location / { return 301 https://$host$request_uri; }
}

server {
  listen 443 ssl http2;
  server_name analytics.example.com;

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

  client_max_body_size 16m;

  add_header X-Frame-Options "SAMEORIGIN" always;
  add_header X-Content-Type-Options "nosniff" always;
  add_header Referrer-Policy "strict-origin-when-cross-origin" always;

  location / {
    proxy_pass http://127.0.0.1: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;
  }
}

If you want a repeatable TLS setup for VPS-hosted services, Caddy is hard to beat. HostMyCode has a practical walkthrough you can reuse: Set Up Let’s Encrypt With Caddy for a VPS Site.

Database choice: why MariaDB is usually the right default

Matomo uses MySQL-compatible databases, and MariaDB is a solid default for VPS installs. It’s widely understood, fast on NVMe, and straightforward to back up.

Start with the database on the same VPS. Split it out only after you measure a real need.

Do three things early:

  • Set utf8mb4 so you don’t hit character issues in referrers and campaign parameters.
  • Watch disk usage on /opt/matomo/db. Analytics tables grow quietly.
  • Schedule archiving so report generation doesn’t happen on-demand during office hours.

Make archiving predictable (and keep it off the critical path)

Archiving is where people get surprised. Without scheduled archiving, Matomo may generate reports when someone opens a dashboard.

That can cause slow pages and sudden CPU/DB IO spikes.

The fix is a cron job that runs archiving on a schedule. With Docker, run the console command inside the container.

The exact command and frequency depend on your setup, so treat this as a pattern:

# Example pattern (run as root or a service user)
# crontab -e
5 * * * * docker compose -f /opt/matomo/compose.yml exec -T matomo php /var/www/html/console core:archive --url=https://analytics.example.com

Hourly works for most sites. For low traffic, you can run it less often.

For high traffic, keep it hourly and size the VPS accordingly.

Backups: what to copy, how often, and what to test

A Matomo backup has two parts. If you only back up one, the restore will be incomplete.

  • MariaDB dump (the analytics data)
  • Matomo volume (config, installed plugins, uploaded assets)

At minimum, run daily backups with 7–30 days retention, plus one longer-lived monthly snapshot.

Store backups off the VPS. Local copies help with fast restores, but they don’t protect you from disk loss.

A practical MariaDB dump command (run from the VPS host):

# Creates a consistent dump; add compression in real use
docker compose -f /opt/matomo/compose.yml exec -T db \
  mariadb-dump -u root -p"$MARIADB_ROOT_PASSWORD" --single-transaction matomo \
  > /backups/matomo/matomo-$(date +%F).sql

Then archive the application data:

tar -C /opt/matomo -czf /backups/matomo/matomo-data-$(date +%F).tar.gz data

Restore testing is the step teams skip, and the step they regret later.

Once per quarter, restore into a throwaway VPS. Confirm you can log in and see reports.

If you want a backup workflow style guide written for operators, borrow the testing mindset from: Set Up PostgreSQL Backups With pg_dump + Restore Test. The tooling differs, but the restore discipline is the same.

Updates: the safe cadence for production

Matomo upgrades are often smooth. “Often” still isn’t a plan.

Treat updates like any other customer-facing service:

  • Step 1: take a fresh DB dump and a tarball of /opt/matomo/data
  • Step 2: pull images (or bump pinned tags) and restart
  • Step 3: run the web updater and verify tracking still records visits
  • Step 4: watch logs and DB size for a day

Typical Docker flow:

cd /opt/matomo
docker compose pull
docker compose up -d
docker compose logs -f --tail=200

One common failure mode is plugin compatibility. If you depend on specific plugins, run upgrades on a staging VPS first.

A small staging box is cheaper than breaking reporting for everyone.

Privacy and compliance knobs you should set on day one

Self-hosting doesn’t automatically make analytics “compliant.” You still need sane defaults and an enforceable policy.

These are the settings teams usually start with:

  • IP anonymization (reduce personal data exposure)
  • Respect Do Not Track if it matches your policy
  • Data retention rules so logs don’t live forever
  • Access controls: separate admin from read-only users, enforce strong passwords, and restrict admin access by IP if possible

If you run other self-hosted services, you’ll recognize the pattern. “Privacy-friendly” still requires explicit settings.

The same thinking shows up in other projects we’ve covered, like running Pi-hole on a VPS where configuration decisions matter as much as the install.

Operational quick checks (the ones you’ll actually use)

When someone says “analytics feels slow,” you need quick signal before you change anything.

These checks cover most VPS builds:

  • CPU/RAM pressure: uptime, free -h, top (watch for archiving spikes)
  • Disk IO and free space: df -h, iostat -xz 1 (NVMe helps, but full disks still crush DB performance)
  • MariaDB size growth: check your volume usage; analytics tables can grow faster after marketing pushes
  • Nginx errors: /var/log/nginx/error.log (timeouts, upstream issues)

If you’re standardizing monitoring, Matomo is a good reason to do it properly. Here’s a proven VPS pattern we’ve shared: Deploy Grafana on a VPS With Docker, TLS, and Backups.

Where Matomo should live in your hosting stack

For most teams, the clean setup is simple. Keep websites and apps where they already run.

Put analytics on a dedicated VPS with one job.

That separation stops analytics load from stealing resources from revenue-critical services.

  • Running WordPress? Keep Matomo separate from your WordPress hosting. WordPress load spikes are unpredictable enough.
  • Running multiple client sites? Consider a larger VPS (or a dedicated server) and allocate per-client views with Matomo’s multi-site support.
  • Need more headroom? Move to a dedicated machine when DB growth and archiving jobs justify it.

If you’re migrating from an existing analytics setup and want the infrastructure move to be uneventful, HostMyCode migrations can help you plan cutover and DNS timing without breaking tracking scripts mid-campaign.

Summary: self-hosted analytics that you can own and operate

Matomo is one of the few open-source analytics platforms that still feels complete for teams that leaned hard on GA.

You get data ownership, predictable infrastructure costs, and privacy defaults you can enforce. The trade is operational. You run it like a service.

Size the VPS for IO, schedule archiving, back up the database, and update with a rollback plan.

If you want a straightforward place to run it, start with a HostMyCode VPS for full control. Or choose managed VPS hosting if you’d rather keep your team focused on product than patch cycles.

Matomo rewards predictable CPU and fast storage, and it gets easier to manage when you can scale the VPS as traffic grows. If you’re replacing GA and want analytics you control end to end, HostMyCode can provision the right-sized VPS and keep it steady with managed VPS hosting options.

FAQ

Should I run Matomo on the same server as my website?

For small sites, you can. For anything revenue-critical, keep Matomo on a separate VPS so archiving and DB writes don’t compete with your web app.

Does Matomo need MariaDB, or can I use something else?

Matomo is designed around MySQL-compatible databases. MariaDB is a common default for self-hosted deployments because it’s easy to operate and back up.

What’s the biggest performance pitfall after deployment?

Skipping scheduled archiving. Without it, report generation can happen during dashboard views, causing slow pages and surprise CPU spikes.

What do I need to back up to restore Matomo completely?

Back up the MariaDB database and the Matomo data directory/volume (configuration, plugins, and uploads). Restoring only one of those usually leads to a broken or incomplete instance.

How do updates usually fail in production?

The most common issues are plugin incompatibilities and running updates without a tested rollback. Take a DB dump first, then upgrade, then verify tracking and dashboards.

Deploy Matomo on a VPS With Nginx and MariaDB | HostMyCode