matomo-org/docker is the official image, and the database is somebody else's container
Official Docker project for Matomo Analytics
At a glance
- What is it?
- The matomo-org/docker repository is the official Docker project for Matomo, the open source analytics platform, and it publishes an Alpine and a Debian flavoured image with an entrypoint script, a php.ini and Apache configuration. The documented workflow starts a MySQL or MariaDB container separately, wires the two together, and stores the application in a volume.
- Who is it for?
- matomo-org/docker suits a team that wants to run web analytics on its own infrastructure with the data staying under its control, and that is comfortable operating a two container setup with a database alongside the application. It does not suit a small site that would rather not run a database and a web server at all, and it is the wrong choice for a log analysis workload unless you are prepared to run the separate import container.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Shell, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
An analytics platform that owns its own data
Matomo, formerly Piwik, is described as the leading open source analytics platform that gives you more than just powerful analytics, and the list that follows is the positioning the project puts in front of users.
It is free open source software, it offers 100% data ownership, it provides user privacy protection, it offers user centric insights, and it is customisable and extensible.
Those five points are the reason this image exists in a form worth reading about. A hosted analytics service is simpler to run, and the data ownership claim is the thing that is hard to get elsewhere, so the audience for the official image is a team that has decided to run the measurement infrastructure themselves. That is a decision about where the page view data of every visitor lands, and it is the kind of decision an organisation makes once and then has to live with.
The extensibility point matters for the image specifically, because the container is the supported way to add plugins and to run log import alongside the live tracking, and the two live in different containers for a reason.
The repository is the official Docker project, its primary language is Shell, and the top level is telling of what it does: Dockerfile-alpine.template and Dockerfile-debian.template, an apache/ directory, a docker-entrypoint.sh, a php.ini, an update.sh script, and fpm/ and fpm-alpine/ directories. The licence is a custom one that GitHub cannot categorise, with the terms in license.md, and the repository is not archived with the last push on 2026-10-05 and no GitHub releases.
Two image flavours and a shared entrypoint
The image is built from a template rather than a fixed Dockerfile, and there are two of them, one Alpine and one Debian. That choice is the usual one and it has a real consequence for the adopter: the two images do not carry the same system packages, so an extension or a shell command that works in one may not work in the other, and the base image you pick is a decision you will be living with.
The entrypoint script, docker-entrypoint.sh, is what turns a generic web server image into a Matomo installation. It is the piece that reads the environment variables and prepares the application, and the presence of a dedicated entrypoint is what makes the MATOMO_DATABASE_* variables work.
The php.ini at the repository root is the PHP configuration that ships with the image, and the apache/ directory holds the web server configuration. generate-stackbrew-library.sh is a small piece of automation, and update.sh is the script that keeps the images current, with a build badge in the README pointing at the job that runs it.
So the repository is doing more than publishing a Dockerfile. It is the whole distribution pipeline, from the image to the package, and that is the reason the project keeps a shell script called update.sh at the top level rather than relying on a manual rebuild.
The database lives in another container
The documented way to run Matomo starts two things, and the first command links them:
docker run -d --link some-mysql:db matomoThe README says this assumes you have already launched a suitable MySQL or MariaDB database container, and the alias matters, because the application is told to look for the database at the host name db. The link is what gives the application container that name for the database container.
The second command adds the port mapping and the volume:
docker run -d -p 8080:80 --link some-mysql:db -v matomo:/var/www/html matomoThe environment variables then do the configuration. The README lists MATOMO_DATABASE_HOST, MATOMO_DATABASE_ADAPTER, MATOMO_DATABASE_TABLES_PREFIX, MATOMO_DATABASE_USERNAME, MATOMO_DATABASE_PASSWORD and MATOMO_DATABASE_DBNAME, and the PHP memory limit is set with PHP_MEMORY_LIMIT.
The variables and the installation wizard are two ways of doing the same thing, and the README describes the wizard route for people who prefer it. Once you are up and running you arrive at the configuration wizard, and if you are using the compose file, at the Database Setup step you enter Database Server as db, Login as MYSQL_USER, Password as MYSQL_PASSWORD and Database Name as MYSQL_DATABASE, and leave the rest as default. Then you continue the installation with the super user.
The practical detail worth checking is that the four wizard values are placeholders for the values from your own compose file rather than literal text, and that the table prefix variable exists because a shared database often needs one.
The volume is what makes the installation survive
The difference between a Matomo you can use and a Matomo you have to set up again tomorrow is one flag.
The mount point in the documented command is /var/www/html, which is where the application lives, so the named volume matomo holds the installation, the configuration, and the plugins you install. Without it, the container is disposable and everything goes with it.
That matters more for Matomo than for a stateless web service, because of what an analytics installation accumulates. The database holds the tracking data, the configuration holds the sites, the goals, the dimensions and the settings a team has tuned, and the plugin directory holds whatever extensions have been added. Rebuilding all of that from a container image would mean re-entering the configuration wizard and re-installing the plugins, so the volume is the minimum bar for anything beyond a demo.
It is also where the operational cost sits. The volume is a piece of state that has to be backed up, and the database container is a second piece of state, so a self hosted Matomo has two things to protect rather than one. That is the trade the 100% data ownership claim buys you, and it is worth pricing before committing to it for a site with real traffic.
For the compose route the README points at a minimal set-up in the .examples folder, at .examples/nginx/compose.yml, which is the example to read before writing your own, since the database aliases and the volume definitions in it are the parts that have to be right.
Log import is a separate container with a Python script
Not every Matomo deployment is a JavaScript tracker. Log analytics reads the access logs of a web server or a load balancer, and the README treats that as a distinct operation with its own container rather than a feature of the main image.
The import script is Matomo's own, at /var/www/html/misc/log-analytics/import_logs.py, and the documented invocation runs it from a python:3-alpine image with the volumes of the Matomo container attached:
docker run --rm --volumes-from="matomo-app-1" --link matomo-app-1 python:3-alpine python /var/www/html/misc/log-analytics/import_logs.py --url=http://ip.of.your.matomo.example --login=yourlogin --password=yourpassword --idsite=1 --recorders=4 /var/www/html/logs/access.logThe arguments are the ones you would expect: the URL of the Matomo instance, the credentials, the site id, the number of recorders, and the path of the log file inside the container. The recorders count is the interesting one, since it is how much of the log file is parsed in parallel.
The reason this is a separate container rather than a Matomo feature is the python:3-alpine image. The main image is a PHP web server, and the import script is Python, so the two runtimes live in different containers and communicate over the link. That is a reasonable design, and it does mean the log pipeline is a second thing to operate, with its own scheduling, its own credentials and its own failure modes, on top of the web application.
The GeoIP line is a removal notice
The last section of the README is short and it is worth reading closely, because of how it is written.
The line about this product including GeoLite data created by MaxMind is struck through, and what follows it is a link to a blog post about significant changes to accessing and using GeoLite2 databases.
That formatting is a removal notice rather than a credit. The bundled GeoIP data is no longer part of the image, and the reason is a change in how the GeoLite2 databases can be obtained and used. The consequence for an adopter is straightforward and easy to miss: an installation that previously worked out of the box may now need a GeoIP database supplied separately before country level reports produce anything.
The rest of the repository follows the same pattern of keeping the operational details close to the code. There is a SECURITY.md for reporting a vulnerability, a .github/ directory for the CI workflow, and the README links the CI build status badge and the automated update.sh job, which together say that the images are rebuilt and republished automatically rather than by hand.
The contribution model is deliberately open. Pull requests are very welcome, and feedback and suggestions are asked for in the issue tracker at github.com/matomo-org/docker/issues. For a project whose main risk is a stale image, having the update path automated and the issue tracker watched is what keeps the deployment current.
The examples predate modern Docker, and that is the practical caveat
The two run commands in the README use --link, and the log import command uses --volumes-from. Both are legacy Docker features, and both have been superseded by the network creation and named volume mechanisms that the current documentation for Docker recommends. The compose example in.examples/nginx/compose.yml is the modern route, and the README points to it directly.
That is not a criticism of the project so much as an observation about the age of the examples, and it has a practical consequence: a reader following the README's first command on a current Docker installation will hit behaviour that no longer works the way the README describes. The compose file is the better starting point for a new deployment, and the individual run commands are still useful for understanding what the topology is, since they show the application talking to a database under the alias db and mounting its own data volume at /var/www/html.
On maintenance, the repository is not archived, the last push was on 2026-10-05, the update.sh job rebuilds the images, and there are no GitHub releases, which is normal for a repository whose artefacts are published to a container registry rather than as release attachments. The licence is a custom one recorded in license.md rather than one of the standard identifiers.
For a team running this in production, the two things that decide whether it works are the alias, since the application and the wizard both expect the database at db, and the volume, since without it the installation is disposable.
Editorial conclusion
matomo-org/docker suits a team that wants to run web analytics on its own infrastructure with the data staying under its control, and that is comfortable operating a two container setup with a database alongside the application. It does not suit a small site that would rather not run a database and a web server at all, and it is the wrong choice for a log analysis workload unless you are prepared to run the separate import container. Verify first that your database container is reachable under the name the wizard expects, that the volume is mounted at the path the image expects, and that the image flavour you pick still has the extensions your deployment needs, since the GeoIP data that used to be bundled is no longer part of it.
Frequently asked questions
What is the matomo-org/docker repository?
It is the official Docker project for Matomo, the open source analytics platform formerly known as Piwik, providing Alpine and Debian image templates, an entrypoint script, Apache configuration, a php.ini and scripts for updating the images and building distribution packages.
How do I run Matomo in Docker?
Start a MySQL or MariaDB container, then run the Matomo image linked to it with a volume for persistent data, as in docker run -d -p 8080:80 --link some-mysql:db -v matomo:/var/www/html matomo. The database alias db is what the installation wizard expects.
Which environment variables does the Matomo image accept?
MATOMO_DATABASE_HOST, MATOMO_DATABASE_ADAPTER, MATOMO_DATABASE_TABLES_PREFIX, MATOMO_DATABASE_USERNAME, MATOMO_DATABASE_PASSWORD and MATOMO_DATABASE_DBNAME, plus PHP_MEMORY_LIMIT for the PHP memory limit. The installation wizard asks for the same values.
How do I import server logs into Matomo?
By running a separate container that executes the python import_logs.py script from the Matomo volume, attaching the Matomo container's volumes and linking to it, as shown in the README with the python:3-alpine image and the --url, --login, --password, --idsite and --recorders arguments.
Is GeoIP data still bundled with the Matomo Docker image?
No. The README strikes through the line about the product including GeoLite data created by MaxMind and links to a post about significant changes to accessing and using GeoLite2 databases, so a GeoIP database now has to be supplied separately.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/matomo-org-docker)Was this useful?