Self-Host Matomo: Full-Featured Web Analytics 2026
TL;DR
Matomo (GPL 3.0, ~19K GitHub stars, PHP) is the most feature-complete open source alternative to Google Analytics. It replicates virtually every Google Analytics feature — funnel analysis, goal tracking, ecommerce conversion tracking, heatmaps (premium plugin), A/B testing, campaign tracking — while keeping 100% of data on your server. Google Analytics 4 is free but complex and sends all data to Google. Matomo Cloud costs $23-$99/month; self-hosted is free for unlimited traffic.
Key Takeaways
- Matomo: GPL 3.0, ~19K stars, PHP — feature-complete GA alternative, full data ownership
- Heatmaps/session recording: Premium plugins (free on self-hosted)
- GDPR compliance: Privacy controls, IP anonymization, consent management built in
- Goals and funnels: Track conversions, multi-step funnel analysis
- Ecommerce: Revenue tracking, product analytics, shopping cart abandonment
- WordPress: Official Matomo WordPress plugin with auto-setup
Matomo vs Plausible vs Umami
| Feature | Matomo | Plausible | Umami |
|---|---|---|---|
| Heatmaps | Yes (premium plugin) | No | No |
| Session recording | Yes (premium plugin) | No | No |
| Funnels | Yes | Basic | No |
| A/B testing | Yes | No | No |
| Ecommerce | Yes | Basic | No |
| Goals | Yes | Yes | Basic |
| Custom segments | Yes | No | No |
| Complexity | High | Low | Low |
| Script size | ~25KB | ~1KB | ~2KB |
| GDPR default | Requires config | GDPR-ready | GDPR-ready |
Part 1: Docker Setup
# docker-compose.yml
services:
db:
image: mariadb:10.11
restart: unless-stopped
environment:
MARIADB_ROOT_PASSWORD: "${MARIADB_ROOT_PASSWORD}"
MARIADB_DATABASE: matomo
MARIADB_USER: matomo
MARIADB_PASSWORD: "${MARIADB_PASSWORD}"
volumes:
- db_data:/var/lib/mysql
matomo:
image: matomo:latest
container_name: matomo
restart: unless-stopped
ports:
- "8080:80"
volumes:
- matomo_data:/var/www/html
environment:
MATOMO_DATABASE_HOST: db
MATOMO_DATABASE_DBNAME: matomo
MATOMO_DATABASE_USERNAME: matomo
MATOMO_DATABASE_PASSWORD: "${MARIADB_PASSWORD}"
MATOMO_DATABASE_ADAPTER: MYSQLI
depends_on:
- db
volumes:
db_data:
matomo_data:
docker compose up -d
Visit http://your-server:8080 → run the setup wizard.
Part 2: HTTPS with Caddy
analytics.yourdomain.com {
reverse_proxy localhost:8080
}
Part 3: Setup Wizard
- Database configuration — auto-detected from environment variables
- Table prefix:
matomo_(default) - Super user: Create admin account
- Add website:
yourdomain.com - Copy tracking code → add to your site
Part 4: Tracking Code Installation
<!-- Add before </head>: -->
<!-- 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 -->
WordPress
Plugin: Matomo Analytics – Ethical Stats. Powerful Insights. (official)
Settings → Matomo Analytics → Connect:
→ Use Matomo on-premise (self-hosted)
→ URL: https://analytics.yourdomain.com
→ Auth token: Settings → Security → Auth tokens
Part 5: Goals and Funnels
Goals
Track conversions:
- Goals → + Add new goal
- Name:
Lead Form Submission - Match: URL → contains →
/thank-you - Or: Custom event →
Contact Form Submit - Revenue:
$0(or set expected value)
Funnels (requires Goals)
Track multi-step conversion:
- Goals → [goal] → + Add funnel
- Steps:
- Step 1: URL contains
/pricing - Step 2: URL contains
/checkout - Step 3: URL contains
/thank-you(conversion)
- Step 1: URL contains
- Funnel report shows dropoff at each step
Part 6: Ecommerce Tracking
// Track product view:
_paq.push(['setEcommerceView',
'product-sku-123', // SKU
'Product Name', // Name
'Electronics', // Category
49.99 // Price
]);
_paq.push(['trackPageView']);
// Add to cart:
_paq.push(['addEcommerceItem',
'product-sku-123',
'Product Name',
'Electronics',
49.99, // Unit price
2 // Quantity
]);
// Track order:
_paq.push(['trackEcommerceOrder',
'ORDER-12345', // Order ID
109.98, // Grand total
89.98, // Subtotal (without shipping/tax)
10.00, // Tax
10.00, // Shipping
false // Discount
]);
Part 7: Privacy Configuration
Matomo requires privacy configuration for GDPR compliance:
# Administration → Privacy → Configure privacy settings:
# 1. IP anonymization (required for GDPR):
Administration → Privacy → Anonymize Visitors IP
→ Anonymize first 2 bytes of IP
# 2. Respect Do Not Track:
Administration → Privacy → Do Not Track
→ Enable: Honor browser Do Not Track header
# 3. Data retention:
Administration → Privacy → Data retention
→ Keep raw data for: 12 months
→ Keep processed/aggregated data for: 24 months
Optional: Consent management
// If you need explicit consent (depends on jurisdiction):
// By default, Matomo doesn't require consent for server-side
// aggregate analytics — check your local law
// Opt-out for users who don't want to be tracked:
if (document.getElementById('optout-checkbox').checked) {
_paq.push(['optUserOut']);
}
Part 8: Segmentation
Create segments to analyze specific user groups:
- Segments → + Add new segment
- Filter:
Country == United StatesANDDevice type == Smartphone - Apply to any report
Examples:
- Organic traffic only:
Referrer type == Search Engine - High-value users:
Number of visits > 3 - Email campaign visitors:
Referrer URL contains utm_source=newsletter
Maintenance
# Update:
docker compose pull
docker compose up -d
# Database backup:
docker exec matomo-db-1 mysqldump -u matomo -p"${MARIADB_PASSWORD}" matomo \
| gzip > matomo-db-$(date +%Y%m%d).sql.gz
# Run archive cron (required for reports):
# Add to crontab:
# */15 * * * * docker exec matomo php /var/www/html/console core:archive --url=https://analytics.yourdomain.com
# Logs:
docker compose logs -f matomo
See also: Plausible and Umami for simpler alternatives
See all open source analytics tools at OSSAlt.com/categories/analytics.