Dockerized Matomo on Ubuntu 16.04

I’ve been hard on CloudAtCost before… they’re still terrible, but I’ve got a lot of use of my one-time purchase. I still use the resources I own to run non-critical applications. Matomo falls into that category.

Anyhoo, my server crashed and had to be deleted. This is how I setup Matomo on Ubuntu 16.04. Do it behind an nginx-proxy/lets-encrypt Docker Composition. This process is very manual and may one day be set up as a proper Docker build. As it stands, there is a lot of manual manipulation within the container.

First, create a project directory:

1
mkdir matomo && cd matomo

Copy and paste this into a file called docker-compose.yml.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
version: '3'
services:
mariadb:
image: 'bitnami/mariadb:latest'
restart: unless-stopped
environment:
- ALLOW_EMPTY_PASSWORD=yes
- MARIADB_USER=bn_matomo
- MARIADB_DATABASE=bitnami_matomo
volumes:
- 'mariadb_data:/bitnami'
matomo:
image: 'bitnami/matomo:latest'
restart: unless-stopped
environment:
- MATOMO_DATABASE_USER=bn_matomo
- MATOMO_DATABASE_NAME=bitnami_matomo
- ALLOW_EMPTY_PASSWORD=yes
- MATOMO_USERNAME=Dan
- MATOMO_EMAIL=someguy@example.com
- VIRTUAL_HOST=matomo.example.com
- LETSENCRYPT_HOST=matomo.example.com
- LETSENCRYPT_EMAIL=someguy@example.com
depends_on:
- mariadb
volumes:
- 'matomo_data:/bitnami'
- './misc:/opt/bitnami/matomo/misc/'
volumes:
mariadb_data:
driver: local
matomo_data:
driver: local
networks:
default:
external:
name: nginx-proxy

Create and execute the container with:

1
docker-compose up -d

This is the time to start (or restart) the nginx-proxy/lets-encrypt composition. Once this is running, your username will be what was set in the docker-compose.yml file described above. In this case, the default credentials are:

  • Username: Dan
  • Password: bitnami

You should be able to login at the domain specified now.

App-level Configuration

matomo works out of the box, but there will be a bunch of things you’ll want to set up at the application level.

Upgrade

Before all that, there’s a weird permissions issue in the container. You’ll want to upgrade matomo, but won’t be able to do so until you fix this. It’s super hacky having to do this from within the container, but that’s what I’m working with at the moment.

From your project directory:

1
docker-compose exec matomo bash

Then, from within the container:

1
2
chown -R daemon:daemon /opt/bitnami/matomo
chmod -R 0755 /opt/bitnami/matomo

Dependencies and Headers

Again, this is super hacky, because now you need to install an editor and a bunch of other dependencies within the container:

1
2
3
apt update
apt install vim git wget autoconf gettext libtool build-essential
vim /opt/bitnami/matomo/config/config.ini.php

Add this to the [General] section:

1
2
3
4
5
force_ssl = 1

; Standard proxy
proxy_client_headers[] = HTTP_X_FORWARDED_FOR
proxy_host_headers[] = HTTP_X_FORWARDED_HOST

Exit the container and restart.

1
docker-compose restart

Config checklist

At this point, everything should be operational on a basic level. Address the following points, and get a lot more use out of matomo.

Personal > Settings

  • Change password
  • Exclude your own visits using a cookie

System > Geolocation

I set up the GeoIP2 (Php) extension, which is supposed to make things faster somehow..

1
docker-compose exec matomo bash

From within the container, clone libmaxminddb:

1
git clone --recursive https://github.com/maxmind/libmaxminddb

Install from inside the cloned directory:

1
2
3
4
5
6
cd libmaxminddb
./bootstrap
./configure
make
make install
ldconfig

Install the extension:

1
2
3
4
5
6
7
cd ..
git clone https://github.com/maxmind/MaxMind-DB-Reader-php.git
cd MaxMind-DB-Reader-php/ext
phpize
./configure
make
make install

Edit php.ini:

1
vim /opt/bitnami/php/lib/php.ini

Add this to the end and save:

1
extension=maxminddb.so

Get the database:

1
2
3
4
cd /opt/bitnami/matomo/misc
wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz
tar -xvfz GeoLite2-City.tar.gz
mv GeoLite2-City_20190115/* .

Exit the container and restart from the host:

1
docker-compose restart

If you refresh the System > Geolocation page, GeoIp 2 (Php) will be operational. Select this option and save.

Websites > Manage

Add all the websites you want track.

Conclusion

I needed to bang this out for my own purposes. I will likely be forced to revisit this when CloudAtCost fails me once again.