matomo dockerized behin apache proxy

matomo

One part of my last project was the creation of internal statistics on web access.
The top dog in the open source sector here is undoubtedly Matomo.
In order to be independent of external circumstances such as PHP version or database, we decided to implement the whole thing with Docker.
The server on which Matomo is to run is a current Ubuntu.
However, there is already a website on the computer that is delivered with an Apache web server and php 8.2.
The web server should therefore be responsible for the following domains

  • www.domain.de
  • matomo.domain.de

The first domain is delivered with Apache by default. However, access to matomo is redirected to the Docker instance via a proxy.

The first thing you see is the Docker configuration and the settings for matomo
This is followed by the Apache configuration. I found this somewhere on the web after a long search. Unfortunately, I forgot to note the source.

services:
  db:
    image: mariadb:10.11
    command: --max-allowed-packet=64MB
    restart: always
    volumes:
      - ./db:/var/lib/mysql:Z
      - ./data:/var/data
    environment:
      - MYSQL_ROOT_PASSWORD=matomo
      - MARIADB_AUTO_UPGRADE=1
      - MARIADB_DISABLE_UPGRADE_BACKUP=1
    env_file:
      - ./db.env

  app:
    image: matomo
    restart: always
    volumes:
      - ./config:/var/www/html/config:z
      - ./logs:/var/www/html/logs:z
      - ./matomo:/var/www/html:z
    environment:
      - MATOMO_DATABASE_HOST=db
    env_file:
      - ./db.env
    ports:
      - 8080:80

volumes:
  db:
  matomo:
docker-compose.yaml
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
MARIADB_AUTO_UPGRADE=1
MARIADB_INITDB_SKIP_TZINFO=1
db.env

So that the security check in the matomo backend is reassured, force_ssl must be set to 1 although matomo has no certificate. See here.

[General]
force_ssl = 1                 ;please add this as well
assume_secure_protocol = 1    ;if you add this
proxy_uri_header = 1
reverse_proxy = 0

proxy_client_headers[] = "HTTP_X_FORWARDED_FOR"
proxy_host_headers[] = "HTTP_X_FORWARDED_HOST"

apache

Now follows the Apache configuration. As briefly mentioned above, the matomo instance runs without a certificate. This is not a problem, as the instance can only be reached under localhost:8080.
To make matomo accessible to others and via SSL, we need Apache as a proxy server at this point.
I admit that Apache is not ideal as a proxy server.
Supposedly nginx is much more performant here. However, my favorite here would be haproxy. It's a bit strange to configure, but it's really great in terms of speed.
However, this is an ongoing project and can't simply be switched over like that.

If the matomo instance is to be accessible at www.domain.de/matomo, this configuration should be selected:

<VirtualHost *:443>
  ServerName www.domain.de
  ServerAlias www.domaain.de
  DocumentRoot /var/www/html/production/releases/current/public
  SSLEngine On
  SSLCertificateKeyFile /etc/ssl/private/wildcard.domain.de.key
  SSLCertificateFile /etc/ssl/private/domain.pem
  
  <Directory "/var/www/html/production/releases/current/public">
    AllowOverride All
  </Directory>

  <Location "/matomo">
    ProxyPreserveHost On
    
    # Rewrite rule to remove /matomo prefix
    RewriteEngine On
    RewriteRule ^/matomo/(.*)$ /$1 [PT]
    
    # Proxy settings
    ProxyPass "http://127.0.0.1:8080/"
    ProxyPassReverse "http://127.0.0.1:8080/"
    
    # Forward client IP and other headers
    RequestHeader set WAF-Forwarded-For %{REMOTE_ADDR}s
    RequestHeader set LB-Forwarded-For %{REMOTE_ADDR}s
    RequestHeader set X-Forwarded-For %{REMOTE_ADDR}s
    
    SetEnvIf Host "^(.*)$" THE_HOST=$1
    RequestHeader setifempty X-Forwarded-Proto https
    RequestHeader setifempty X-Forwarded-Host %{THE_HOST}e
    RequestHeader edit X-Forwarded-Host (.*) $1/matomo
    ProxyAddHeaders Off
  </Location>
</VirtualHost>

However, if you want to give the Matomo instance a completely separate subdomain, this can be configured in this way:

<VirtualHost *:443>
    ServerName matomo.domain.de
    ServerAlias matomo.domain.de
  
    # SSL Configuration
    SSLEngine On
    SSLCertificateKeyFile /etc/ssl/private/wildcard.dgbrs.de.key
    SSLCertificateFile /etc/ssl/private/dgbrs.pem

    # Proxy Einstellungen
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:8080/
    ProxyPassReverse / http://127.0.0.1:8080/

    # Logging
    ErrorLog ${APACHE_LOG_DIR}/matomo.dgbrs.de_error.log
    CustomLog ${APACHE_LOG_DIR}/matomo.dgbrs.de_access.log combined

    # Optional: Zusätzliche Sicherheitsheader
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set X-Content-Type-Options "nosniff"
</VirtualHost>

Summary

As always, I am enthusiastic about Docker. This technology makes it so easy to work with different tools.
You don't always need a new server to run things side by side.
I would also like to take this opportunity to thank the tireless container tinkerers who put together a ready-made matomo for us.

Comments

No Comments

Write comment

* These fields are required