Skip to main content
A split-panel illustration comparing web analytics solutions. On the left, a complex, cluttered Matomo dashboard labeled 'Complexity'. A glowing arrow points to the right, showing a clean, minimalist Plausible dashboard with a privacy shield, labeled 'Privacy'. Text at the bottom reads 'Migration to Simplicity & Privacy'.

Deploying Plausible with Docker: A Lightweight Matomo Alternative

5 min 973 words

My Personal Need for Web Analytics

Web analytics involves gathering, measuring, and analyzing user behavior data on a website. For companies building consumer products, measuring this data is crucial. It allows them to monitor product popularity, track usage peaks, and measure the impact of new features—specifics that vary heavily depending on the audience and product type.

That is not my situation. I run a blog, and I simply want to keep an eye on visit counts. My goal is to get a rough idea of my blog’s popularity, identify trending articles, and gain basic insights into visitor demographics and browser usage.

When looking for analytics solutions, the undisputed leader is Google Analytics. However, as noted in this article, its market share is declining, largely due to fundamental incompatibilities with modern data protection regulations. Google Analytics (UA/GA4) has faced bans in several jurisdictions for failing to comply with GDPR standards set by authorities like the CNIL between 2020 and 2023. Consequently, privacy-focused, GDPR-compliant solutions are gaining traction. One of the most prominent is Matomo, a comprehensive alternative to Google Analytics.

I won’t dive too deep into Matomo, as I am not an expert and my use case is extremely basic: tracking visitor numbers. I initially adopted it for two main reasons:

  1. GDPR Compliance: It’s one of the few solutions that doesn’t legally require a cookie banner.

  2. Self-Hosting: Beyond my passion for self-hosting, owning the infrastructure guarantees total control over how visitor data is used.

In this article, I will detail how to install Matomo. Then, I will explain why I eventually sought an alternative and why I switched to Plausible. Finally, I’ll provide a guide on how to deploy Plausible on your own infrastructure.

Part 1: Matomo

According to its creators, Matomo is the “Google Analytics alternative that protects your data and your customers’ privacy.” Used by over a million websites, it is recognized as GDPR-compliant by the CNIL, the French administrative body dedicated to data privacy.

Matomo offers both a SaaS solution and an on-premise self-hosted version. I chose the latter. It can be deployed via a web server script, a WordPress plugin, or Docker. I will focus on the Docker implementation using Docker Compose and MariaDB, deployed on a Raspberry Pi 5 (Raspbian OS Lite 64-bit).

Installation

Here is the docker-compose.yml:

networks:
  matomo_default:

services:
  matomo-db:
    container_name: "matomo-db"
    environment:
      - "MARIADB_AUTO_UPGRADE=1"
      - "MARIADB_DISABLE_UPGRADE_BACKUP=1"
      - "MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}"
      - "LANG=C.UTF-8"
    expose:
      - "3306/tcp"
    image: "mariadb:latest"
    networks:
      - "matomo_default"
    restart: "always"
    volumes:
      - "matomo-db:/var/lib/mysql"

  matomo-app:
    container_name: "matomo-app"
    image: "matomo:latest"
    networks:
      - "matomo_default"
    environment:
      - "MATOMO_DATABASE_HOST=matomo-db"
    ports:
      - "8080:80/tcp"
    restart: "always"
    volumes:
      - "matomo-data:/var/www/html"

volumes:
    matomo-db:
    matomo-data:

You must create a .env file containing a strong root password for MariaDB:

MYSQL_ROOT_PASSWORD=a_super_strong_and_secret_password

Note: If you prefer binding volumes to local host folders, ensure you assign the correct ownership. For a folder named matomo-data:

sudo chown -R www-data:www-data matomo-data

Launch the stack:

docker compose up -d

Next, configure your DNS to point your domain to port 8080 of your host (via reverse proxy). If you are unfamiliar with this, check out my previous guide on DNS and routing.

Tip: Perform the setup wizard through your public domain URL. This saves you from manually editing PHP config files later to whitelist your domain.

First step of the Matomo setupFirst step of the Matomo setup

Follow the wizard:

  • Database Server: matomo-db

  • Login: root

  • Password: (from your .env file)

  • Database Name: matomo

  • Adapter: PDO/MYSQL

Second step of the Matomo setupSecond step of the Matomo setup

Create your admin credentials, define your website URL, and copy the provided tracking code.

Last step of the Matomo setupLast step of the Matomo setup

Insert this snippet into your website’s <head>. If you use Content Security Policy (CSP) headers, you must whitelist Matomo:

script-src-elem
    ...
    https://matomo.laromierre.com/matomo.js
    https://matomo.laromierre.com/index.php

connect-src
    ...
    https://matomo.laromierre.com/

For more on CSPs, see my article on Hugo security headers.

Addendum: Privacy Policy

Even with privacy-friendly tools, transparency is key. I recommend drafting a privacy policy inspired by Matomo’s own policy and including an opt-out iframe:

<div id="matomo-opt-out"></div>
<script src="https://my-matomo-site.org/index.php?module=CoreAdminHome&action=optOutJS&div=matomo-opt-out"></script>

Moving from Matomo to Plausible

Matomo is reliable and robust, but I found it overkill. My needs are minimal: page views and visitor counts. I don’t need complex funnels or heatmaps.

I wanted something lightweight, Docker-friendly, and dead simple to configure. My research led me to Plausible.

Why Plausible?

Plausible positions itself as an “easy to use and privacy-friendly Google Analytics alternative.” It is:

  1. Open Source: Available on GitHub.

  2. Self-Hostable: Fits my infrastructure.

  3. Lightweight: The script is < 1 KB (vs Matomo’s heavier payload).

  4. Cookie-less: It goes further than Matomo by not using cookies at all.

Matomo vs Plausible: At a Glance

Before installing, here is a quick breakdown of why Plausible suited my needs better:

FeatureMatomo (On-Premise)Plausible (Self-Hosted)
ComplexityHigh (Many features)Low (Essential metrics only)
Script Size~22 KB< 1 KB
CookiesYes (Can be disabled)No (Cookie-less by design)
DatabaseMariaDB/MySQLClickHouse + PostgreSQL
UI/UXDense, Enterprise-likeClean, Minimalist
Resource UsageModerate to HighVery Low

For a detailed comparison (albeit biased), check out Plausible vs Matomo.

Installation and Configuration

Back-end (Docker Compose)

Start by cloning the Plausible Community Edition.

I recommend renaming compose.yml to docker-compose.yml and modifying it directly instead of using override files for simplicity. I strongly recommend using a reverse proxy like Traefik.

Here is a streamlined docker-compose.yml:

services:
  plausible_db:
    image: postgres:16-alpine
    restart: always
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=postgres
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      start_period: 1m

  plausible_events_db:
    image: clickhouse/clickhouse-server:24.3.3.102-alpine
    restart: always
    volumes:
      - event-data:/var/lib/clickhouse
      - event-logs:/var/log/clickhouse-server
      - ./clickhouse/logs.xml:/etc/clickhouse-server/config.d/logs.xml:ro
      - ./clickhouse/ipv4-only.xml:/etc/clickhouse-server/config.d/ipv4-only.xml:ro
      - ./clickhouse/low-resources.xml:/etc/clickhouse-server/config.d/low-resources.xml:ro
    ulimits:
      nofile:
        soft: 262144
        hard: 262144
    healthcheck:
      test: ["CMD-SHELL", "wget --no-verbose --tries=1 -O - http://127.0.0.1:8123/ping || exit 1"]
      start_period: 1m

  plausible:
    image: ghcr.io/plausible/community-edition:v2.1.5
    restart: always
    ports:
      - "80:80"
    command: sh -c "/entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh run"
    depends_on:
      plausible_db:
        condition: service_healthy
      plausible_events_db:
        condition: service_healthy
    volumes:
      - plausible-data:/var/lib/plausible
    ulimits:
      nofile:
        soft: 65535
        hard: 65535
    environment:
      - TMPDIR=/var/lib/plausible/tmp
      - BASE_URL=${BASE_URL}
      - SECRET_KEY_BASE=${SECRET_KEY_BASE}
      - HTTP_PORT=80

volumes:
  db-data:
  event-data:
  event-logs:
  plausible-data:

Run the stack:

docker compose up -d

Access the dashboard at http://<host-ip> (or your configured domain) to create your account.

Plausible setup screenPlausible setup screen

(For advanced configurations like External PostgreSQL or Docker Swarm, please refer to the snippets in the original code blocks above).

Front-end Configuration

After setting up your account and defining your domain, Plausible provides a snippet:

<script defer data-domain="${label}" src="${plausible_domain}/js/script.js"></script>

Awaiting first pageview
Awaiting first pageview

Integration with Hugo

For my Hugo blog, I used the plausible-hugo module, which simplifies the process:

  1. Add the module to config.toml:

    [module]
       [[module.imports]]
       path = "github.com/divinerites/plausible-hugo"
  2. Configure settings:

    [plausible]
        enable = true
        selfhosted_domain = "myplausible.example.com"
        domain = "my-domain-id"
  3. Initialize:

    hugo mod init github.com/divinerites/plausible-hugo
    hugo mod get -u
  4. Inject the partial in your <head>:

    {{ partial "plausible_head.html" . }}

If you are hosting on Netlify with CSP headers, you’ll need to proxy the scripts to avoid ad-blockers. Add this to netlify.toml:

[[redirects]]
  from = "/misc/js/script.js"
  to = "https://plausible.io/js/script.js"
  status = 200
  force = true

[[redirects]]
  from = "/misc/api/event"
  to = "https://plausible.io/api/event"
  status = 200
  force = true

And update your CSP:

script-src-elem https://plausible.laromierre.com/js/script.file-downloads
connect-src https://plausible.laromierre.com

Once deployed, visit your site, and your Plausible dashboard should light up!

Plausible dashboard with dataPlausible dashboard with data

Conclusion

My journey from Matomo to Plausible highlights the importance of choosing the right tool for the job. Both are excellent, GDPR-compliant alternatives to Google Analytics. However, for a personal blog or a small project, Plausible’s lightweight, privacy-first, and “set-and-forget” approach makes it the superior choice.

It respects your resources (RAM/CPU) and your users’ data equally. If you want analytics that just work without the bloat, I highly recommend making the switch.