Self-hosting Matomo with a shared MySQL database

The official way to self-host Matomo Analytics is using it's own dedicated MySQL container along with a container for Matomo. I'm hosting it on a VPS with limited resources that's already running a MySQL database, so I wanted Matomo to connect to the MySQL database I already had.

Host networking doesn't work

I thought it would be easy to do: I would just run the container with host networking. That doesn't work because Matomo runs on port 80, and Nginx is already running on port 80 on my host, so that idea didn't work.

Solution: Have MySQL listen on a private IP address the Matomo container can see.

Starting in MySQL 8.0.13, you can set bind-address to listen on multiple addresses. So I update this MySQL setting to listen also on the private container network.

On my Ubuntu server, the file I updated was /etc/mysql/mysql.conf.d/mysqld.cf

bind-address		= 127.0.0.1,10.88.0.1

Why 10.88.0.1?  From networksctl status, I could see this range was part of the container network.

Later, I found /etc/cni/net.d/87-podman.conflist which defines the container networks. I didn't change anything there, but it clarifies the container network is in the 10.88.0.0/16 subnet, with a gateway of 10,88.0.1.

Managing Matomo container with Podman

Here's how I manage my Matomo container with Podman. Suggestions for improvement welcome. You can see I set a hardcoded IP addresss for the Matomo container, but I don't think in the end that was necessary for this to work.

[Unit]
Description=Mamoto web analytics service
Documentation=https://github.com/matomo-org/matomo

[Service]
Restart=on-failure

Type=simple
WorkingDirectory=/sites/stats.example.com

TimeoutStartSec=5m
# The following pattern rebuilds the container from the image during each restart or reload.
# The leading "-" prefix to some commands tells systemd to continue if the command fails,
# allowing the commands to work whether the container has ever been created or not.
# The --env-host option passes through the environment variables set by systemd
# Unless your Ubuntu version is >=20.04, use absolute paths here.
ExecStartPre=-/usr/bin/podman rm "matomo"
ExecStart=/usr/bin/podman run --ip=10.88.0.2 --publish 127.0.0.1:8001:80 --name=matomo --volume /sites/stats.example.com:/var/www/html --env-host docker.io/library/matomo:4
ExecReload=-/usr/bin/podman stop "matomo"
ExecReload=-/usr/bin/podman rm "matomo"
ExecStop=-/usr/bin/podman stop "matomo"
StandardOutput=journal

# Matomo settings
Environment=MATOMO_DATABASE_HOST="10.88.0.1"
Environment=MATOMO_DATABASE_DBNAME="matomo"
Environment=MATOMO_DATABASE_USERNAME="matomo"
Environment=VIRTUAL_HOST=stats.example.com
Environment=LETSENCRYPT_HOST=stats.example.com
Environment=LETSENCRYPT_EMAIL=mark@example.com
# The UID/GID here should match the values of your matomo user
Environment=PHP_UID=1003
Environment=PHP_GID=1003
Environment=PHP_HOME=/sites/stats.example.com
Environment=PHP_USER=matomo

# EnviromentFile is used for values that should not be commited to Git.
# This includes MATOMO_DATABASE_PASSWORD
EnvironmentFile=/etc/default/matomo.env

# When systemctl enable is used, make this start at boot
[Install]
WantedBy=multi-user.target
html