DEV Community

Cover image for Using Matomo on Angular
Fábio Borges
Fábio Borges

Posted on

Using Matomo on Angular

If you haven’t heard about Matomo, yet, then you should check this out.

Matomo is a

“Google Analytics alternative that protects your data and your customers' privacy” and that “gives you 100% data ownership”.

This is great news for those of you who are GDPR aware and unfortunately (for some) aren’t able to use cloud services like Google Analytics.

OK, so where can we start?

On this guide, I’ll help you configure an “on-premise” installation of Matomo using Docker with nginx, and running it on Angular.

Reference material

All the info I’m sharing can be found at matomo-org/docker and EmmanuelRoux/ngx-matomo.

Some tweaks can be found in my git matomo-angular-docker

I’m also assuming you already installed docker on your machine.

Setting up your docker

This setup is for Matomo version 3 and includes a database with MySQL image (you could use MariaDB as well), the Matomo app and the web using nginx.

First thing is first, let’s get the docker-compose.yaml file.

version: "3"

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

  app:
    image: matomo:fpm-alpine
    restart: always
    links:
      - db
    volumes:
      - matomo:/var/www/html
    environment:
      - MATOMO_DATABASE_HOST=db
      - PHP_MEMORY_LIMIT=2048M
    env_file:
      - ./db.env

  web:
    image: nginx:alpine
    restart: always
    volumes:
      - matomo:/var/www/html:ro
      - ./matomo.conf:/etc/nginx/conf.d/default.conf:ro
    ports:
      - 8080:80

volumes:
  db:
  matomo:
Enter fullscreen mode Exit fullscreen mode

Nothing fancy here, Matomo will be running on port 8080, and you can of course change the values like MYSQL_ROOT_PASSWORD or the restart option (which if you don’t know, keeps restarting the container in case of failure).

In case you didn’t notice, we’re referencing two other files in this compose.

The db.env where we will set some variables for MySQL image

MYSQL_PASSWORD=matomo
MYSQL_DATABASE=matomo
MYSQL_USER=matomo
MATOMO_DATABASE_ADAPTER=mysql
MATOMO_DATABASE_TABLES_PREFIX=matomo_
MATOMO_DATABASE_USERNAME=matomo
MATOMO_DATABASE_PASSWORD=matomo
MATOMO_DATABASE_DBNAME=matomo
Enter fullscreen mode Exit fullscreen mode

And matomo.conf file where we’re defining some behaviour for Matomo nginx.

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
Enter fullscreen mode Exit fullscreen mode

Up up we go!

Hot air balloon

Time to run the docker-compose file. For this, just open your favourite terminal (I like ZSH!) on the root of the folder where you have the file in and execute the command docker-compose up. This will create the needed volumes and images for the new docker containers.

If you now head to your http://localhost:8080/, and you did exactly as I said, you’ll see that Matomo is ready to be configured.

Setting up Matomo

On the Database Setup, make sure you enter the inputs for the values defined on the docker-compose.yaml file.

On the Superuser step just set up your credentials as you want them and then on Set up a Website make sure to define your target, in this example it will be https://localhost:4200 which is where we will be running our angular application.

Problems ahead?

developer thinking

On ending the setup, you might be faced with a warning stating that Matomo has not been configured to run on your localhost 8080 port.
matomo error

The problem is not the problem, savvy?

To get around this, we need to change Matomo config.ini.php file inside the app container that was created by our compose file.

The deal is that we basically need to tell Matomo that the port we’re using is a trusted host.

To do this, run the following command from same folder where docker-compose.yaml is: docker exec -u 0 -it matomo_app /bin/sh take in consideration that matomo_app is your container name (in some scenarios you might end up with and suffix like matomo_app_1, just check the name using docker ps)

If the command ran successfully, then we should be inside the container.

Now we'll use vi to edit the Matomo configuration file by running the command vi config/config.ini.php (make sure your path is /var/www/html).
Press the key I to insert data, navigate to the [General] section and then append the following:

[General]
trusted_hosts[] = "localhost:8080"
cors_domains[] = *
Enter fullscreen mode Exit fullscreen mode

Once finished the editing, press the ESC key, write :wq and press enter. This will write and quite the editing of the file.

Trusted hosts will allow you to run Matomo in your defined port (in this scenario it’s 8080) and the CORS will allow your local project to call Matomo on the same port (look at me, doing magic and stuff)

Are we there yet?

Almost there, kids. So we got everything up and running, and the only missing link is adding the Matomo package to your angular project and set it up.

On the angular project, install the package npm install --save @ngx-matomo/tracker followed by npm install --save @ngx-matomo/router and then import the modules NgxMatomoTrackerModule and NgxMatomoRouterModule into your app.module, so it looks like this

import { NgModule } from '@angular/core';
import { NgxMatomoTrackerModule } from '@ngx-matomo/tracker';
import { NgxMatomoRouterModule } from '@ngx-matomo/router';

@NgModule({
  imports: [
    // ...
    NgxMatomoTrackerModule.forRoot({
      siteId: 'YOUR_MATOMO_SITE_ID', // your Matomo's site ID (find it in your Matomo's settings)
      trackerUrl: 'http://localhost:8080/', // your matomo server root url
    }),
    NgxMatomoRouterModule,
  ],
  // ...
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

Are we done yet?

Matomo real time dashboard

Oh, yes, we are! The configuration above is the bare minimum, so you'll have a report for every routing navigation you do. Try navigating back and forward on your angular app and then check the Matomo dashboard, you should see some data appearing.

This was a very fun and educational exercise for me, and I hope I’ve helped you set up your machine as well.
As always, please feel free to advise, share ideas and, comment! See you soon!

people bump fist

Special thanks to Ashkan Forouzani, Tim Gouw and Ricardo Rocha for the photos.

Top comments (0)