Categories: Docker

How to install Matomo with docker-compose

I’ve never understand how much power has the owner of a website/app in terms of data until I started having websites.

I tried Google Analytics since I wanted to understand a little bit more about my website but I understood immediately that it was very invasive.

It’s my website, I write posts but still I don’t know how user read them. If they read them.

It’s not about spying, it’s about understanding what is good from what is not.

Imagine the owner of a shop with a foulard that cover his view and earplugs in his hears.  Taking care of the shop would me a mess: are clients coming inside the shop? If yes, when they go out? What if most of them go out after checking prices? Do I want this? It could be, maybe I’m aiming to a very particular niche, but since they came in maybe I can offer something to them.

A webmaster or a blogger without a good analytic tool is blind and deaf and can’t understand what happening to his websites’s visitors.

Don’t misunderstand me, I’m not the kind of person that loose more time on analytics than writing (I usually spend most of my time fixing what it’s not working), and I think that having a good open source analytic tool like Matomo doesn’t change the game.

Docker and docker-compose

I suppose you already know what Docker is and that you have both, docker and docker compose, on your host system.

Indeed we’ll use docker compose to run Matomo and if you follow this tutorial everything should work.

If not blame who updated Matomo or docker. 🙂
(and write a comment here so I can update the post)

Matomo docker-compose

Ok, first thing to say is that I took the docker-compose.yml from the official Matomo Github repository.

Create a folder called matomo.

mkdir matomo

Then let’s go inside that folder.

cd matomo

Now you have to create three files. If nano does’t work use sudo in front of nano.

Docker-compose.yml

nano docker-compose.yml

version: '3'

services:
  db:
    image: mariadb
    command: --max-allowed-packet=64MB
    restart: always
    volumes:
      - db:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=
    env_file:
      - ./db.env

  app:
    image: matomo:fpm-alpine
    restart: always
    links:
      - db
    volumes:
#      - ./config:/var/www/html/config:rw
#      - ./logs:/var/www/html/logs
      - matomo:/var/www/html
    environment:
      - MATOMO_DATABASE_HOST=db
    env_file:
      - ./db.env

  web:
    image: nginx:alpine
    restart: always
    volumes:
      - matomo:/var/www/html:ro
      # see https://github.com/matomo-org/matomo-nginx
      - ./matomo.conf:/etc/nginx/conf.d/default.conf:ro
    ports:
      - 8080:80

volumes:
  db:
  matomo:

db.env

Here we specify our enviroment variables. You can directly copy and paste it but make sure to change the password (XXXXXXXX and YYYYYYYY).

nano db.env

MYSQL_PASSWORD=XXXXXXXX
MYSQL_DATABASE=matomo
MYSQL_USER=matomo
MATOMO_DATABASE_ADAPTER=mysql
MATOMO_DATABASE_TABLES_PREFIX=matomo_
MATOMO_DATABASE_USERNAME=matomo
MATOMO_DATABASE_PASSWORD=YYYYYYYY
MATOMO_DATABASE_DBNAME=matomo

Matomo.conf
You can copy and paste this without modify anything.
nano matomo.conf

upstream php-handler {
    server app:9000;
}

server {
    listen 80;

    add_header Referrer-Policy origin; # make sure outgoing links don't show the URL to the Matomo instance
    root /var/www/html; # replace with path to your matomo instance
    index index.php;
    try_files $uri $uri/ =404;

    ## only allow accessing the following php files
    location ~ ^/(index|matomo|piwik|js/index|plugins/HeatmapSessionRecording/configs).php {
        # regex to split $uri to $fastcgi_script_name and $fastcgi_path
        fastcgi_split_path_info ^(.+\.php)(/.+)$;

        # Check that the PHP script exists before passing it
        try_files $fastcgi_script_name =404;

        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param HTTP_PROXY ""; # prohibit httpoxy: https://httpoxy.org/
        fastcgi_pass php-handler;
    }

    ## deny access to all other .php files
    location ~* ^.+\.php$ {
        deny all;
        return 403;
    }

    ## disable all access to the following directories
    location ~ /(config|tmp|core|lang) {
        deny all;
        return 403; # replace with 404 to not show these directories exist
    }
    location ~ /\.ht {
        deny all;
        return 403;
    }

    location ~ js/container_.*_preview\.js$ {
        expires off;
        add_header Cache-Control 'private, no-cache, no-store';
    }

    location ~ \.(gif|ico|jpg|png|svg|js|css|htm|html|mp3|mp4|wav|ogg|avi|ttf|eot|woff|woff2|json)$ {
        allow all;
        ## Cache images,CSS,JS and webfonts for an hour
        ## Increasing the duration may improve the load-time, but may cause old files to show after an Matomo upgrade
        expires 1h;
        add_header Pragma public;
        add_header Cache-Control "public";
    }

    location ~ /(libs|vendor|plugins|misc/user) {
        deny all;
        return 403;
    }

    ## properly display textfiles in root directory
    location ~/(.*\.md|LEGALNOTICE|LICENSE) {
        default_type text/plain;
    }
}

# vim: filetype=nginx

I hope it works for you as it worked for me. If you have any suggestions or if you encountered in any problem feel free to leave a message here.

Alessandro Oppo

Alessandro è un milanese che vorrebbe scappare da Milano, è appassionato di informatica ma vorrebbe vivere senza telefono, è un artigiano eppure vorrebbe robotizzare tutto, impara una cosa e già vorrebbe studiare dell’altro. Autodidatta da sempre, gli piace sbattere la testa finché tutto non funziona come vuole lui, spesso ci riesce anche! Visita il suo blog personale alexoppo.com Il motto che si ripete dentro la testa è: “Se ci sono riusciti gli altri ci posso riuscire anche io”.

Share
Published by
Alessandro Oppo

Recent Posts

Ponti sospesi: cosa abbiamo sbagliato? cosa si potrebbe fare?

Poco prima di Natale ho avuto la fortuna di poter partecipare a un evento chiamato…

12 mesi ago

Siamo quel che facciamo? – racconto breve

Armando quel giorno era particolarmente stanco. Tutto, per quanto andasse bene, sembrava metterlo sotto pressione.…

1 anno ago

Il limite è sempre la mente – Racconto breve

Armando guardò l’orologio e vide il proprio riflesso sul quadrante bianco. Il riflesso però non…

1 anno ago

L’ultimo giorno del carcere – Racconto breve

I muri sono muri, lo sono sempre, anche quando le porte sono aperte. Era la…

1 anno ago

Riflessioni sul carcere

Pochi di noi riflettono sull’esistenza nella nostra società del carcere. Il carcere è la concretizzazione…

2 anni ago

Come dovremmo dialogare secondo me

Spesso intraprendiamo delle conversazioni e delle chiacchierate piuttosto inconsapevolmente. Voglio dire che non siamo molto…

2 anni ago