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:
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
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
Up up we go!
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?
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.
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[] = *
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 {}
Are we done yet?
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!
Special thanks to Ashkan Forouzani, Tim Gouw and Ricardo Rocha for the photos.
Top comments (0)