Webclat / Martech Practice
Webclat / Martech Practice  /  qa  /  matomo

Why does self-hosted Matomo fail to install/log in behind nginx, Docker, or a managed database?

Answer in brief

The three common self-hosting failure classes are: nginx not passing the correct rewrite rules for Matomo's PHP front controller, Docker volume or permission mismatches that stop Matomo from writing its config file or cache directories, and managed-database defaults (like MySQL 8's sql_require_primary_key) rejecting Matomo's own schema migrations because the provider enforces stricter defaults than a self-managed install expects.

Why this happens

Matomo ships assuming a fairly traditional Apache-plus-mod_php-plus-self-managed-MySQL hosting environment, and each popular alternative changes an assumption Matomo depends on. nginx does not include the same rewrite behavior out of the box, so without an explicit configuration matching Matomo's own recommended nginx config, both the tracking endpoint and admin routes can misbehave.

Docker containers frequently mount the Matomo application directory with a host-side UID/GID that does not match the container's PHP-FPM user, so writes to config.ini.php or the tmp/ cache directory fail silently with permission errors that surface as a confusing "can't write configuration" install error.

Managed database services often enable stricter SQL modes by default than a self-hosted MySQL instance would - a strict primary-key requirement is one specific example that blocks schema updates outright.

Fix it

  1. Use Matomo's official published nginx configuration snippet, not a generic PHP-app config - it explicitly handles the tracking endpoint, static plugin assets, and blocking access to config/ and tmp/.
  2. In Docker, confirm the container's PHP-FPM process UID matches the ownership of the mounted volume (chown the host directory to match, or set the user in your compose file) so Matomo can write config.ini.php and its cache directories.
  3. For managed MySQL with strict SQL modes, check Matomo's own System Check page before install - it flags unsupported SQL modes directly; disable sql_require_primary_key at the instance level if your provider allows it, or use a self-managed MySQL/MariaDB instance instead.
  4. Run Matomo's built-in System Check tool as the first troubleshooting step for any self-hosted failure - it reports PHP extension, permission, and database-compatibility issues directly rather than guessing from install-page error text.
  5. Confirm PHP version and required extensions (especially pdo_mysql, gd, mbstring) match Matomo's current minimum requirements for the release you are installing - version drift is a frequent silent cause of installs that simply fail with no clear error.

How to verify it worked

Load /index.php and confirm the Matomo login screen renders without a PHP error or blank page; load /matomo.php directly and confirm it returns the expected 1x1 pixel response, not a 404 or 500, confirming the tracking endpoint is reachable through your configuration. Re-run Administration > System Check post-install to confirm no red flags remain.

Still Seeing This After Trying the Fix?

Send us what you are seeing - the console error, the Network tab, the Live View output. We trace tracking implementations for a living and can usually tell you what is actually happening in one look.

Ask An Engineer