Files
matomo-bootstrap/README.md
Kevin Veen-Birkenbach 9e267ec83f
Some checks failed
ci / tests (push) Has been cancelled
Added github sponsor buttons
2026-01-02 13:00:00 +01:00

312 lines
7.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# matomo-bootstrap
[![GitHub Sponsors](https://img.shields.io/badge/Sponsor-GitHub%20Sponsors-blue?logo=github)](https://github.com/sponsors/kevinveenbirkenbach) [![Patreon](https://img.shields.io/badge/Support-Patreon-orange?logo=patreon)](https://www.patreon.com/c/kevinveenbirkenbach) [![Buy Me a Coffee](https://img.shields.io/badge/Buy%20me%20a%20Coffee-Funding-yellow?logo=buymeacoffee)](https://buymeacoffee.com/kevinveenbirkenbach) [![PayPal](https://img.shields.io/badge/Donate-PayPal-blue?logo=paypal)](https://s.veen.world/paypaldonate)
Headless bootstrap tooling for **Matomo**. Automates **first-time installation** and **API token provisioning** for fresh Matomo instances.
---
## Features
- 🚀 **Fully headless Matomo installation**
- Drives the official Matomo web installer using **Playwright**
- Automatically skips the installer if Matomo is already installed
- 🔐 **API token provisioning**
- Creates an **app-specific token** via an authenticated Matomo session
- Compatible with **Matomo 5.3.x** Docker images
- 🧪 **E2E-tested**
- Docker-based end-to-end tests included
- ❄️ **First-class Nix support**
- Flake-based packaging and pinned `flake.lock`
- Uses `nixpkgs` browsers via `playwright-driver` (no Playwright downloads)
- 🧼 **Token-only stdout contract**
- **stdout contains only the token** (safe for scripting)
- Logs go to **stderr**
---
## Requirements
- A running Matomo instance (e.g. via Docker)
- For fresh installs:
- Chromium (provided by Playwright or by the Playwright base container image)
---
## Installation
### Nix (recommended)
Run directly from the repository:
```bash
nix run github:kevinveenbirkenbach/matomo-bootstrap
```
In Nix mode, browsers are provided via `nixpkgs` (`playwright-driver`) and Playwright downloads are disabled.
---
### Python / pip
Requires **Python ≥ 3.10**:
```bash
pip install matomo-bootstrap
python -m playwright install chromium
```
---
### Docker image (GHCR)
Pull the prebuilt image:
```bash
docker pull ghcr.io/kevinveenbirkenbach/matomo-bootstrap:stable
# or:
docker pull ghcr.io/kevinveenbirkenbach/matomo-bootstrap:latest
```
---
## Usage
### CLI
```bash
matomo-bootstrap \
--base-url http://127.0.0.1:8080 \
--admin-user administrator \
--admin-password 'AdminSecret123!' \
--admin-email administrator@example.org \
--token-description my-ci-token
```
On success, the command prints **only the token** to stdout:
```text
6c7a8c2b0e9e4a3c8e1d0c4e8a6b9f21
```
---
### Environment variables
All options can be provided via environment variables:
```bash
export MATOMO_URL=http://127.0.0.1:8080
export MATOMO_ADMIN_USER=administrator
export MATOMO_ADMIN_PASSWORD='AdminSecret123!'
export MATOMO_ADMIN_EMAIL=administrator@example.org
export MATOMO_TOKEN_DESCRIPTION=my-ci-token
matomo-bootstrap
```
---
### Debug mode
Enable verbose logs (**stderr only**):
```bash
matomo-bootstrap --debug
```
---
## Docker Compose integration (one-shot bootstrap)
### Why “one-shot”?
The bootstrap container is meant to:
1. Run once,
2. Print the token to stdout,
3. Exit with code `0`.
You should **not** start it automatically on every `docker compose up`.
Instead, start Matomo normally, then run the bootstrap via `docker compose run`.
The cleanest Compose pattern is to put `bootstrap` behind a **profile**.
---
### Example `docker-compose.yml` (recommended: `profiles`)
```yaml
services:
db:
image: mariadb:11
container_name: matomo-db
restart: unless-stopped
environment:
MARIADB_DATABASE: matomo
MARIADB_USER: matomo
MARIADB_PASSWORD: matomo_pw
MARIADB_ROOT_PASSWORD: root_pw
volumes:
- mariadb_data:/var/lib/mysql
healthcheck:
test: ["CMD-SHELL", "mariadb-admin ping -uroot -proot_pw --silent"]
interval: 5s
timeout: 3s
retries: 60
matomo:
image: matomo:5.3.2
container_name: matomo
restart: unless-stopped
depends_on:
db:
condition: service_healthy
ports:
- "${MATOMO_PORT:-8080}:80"
environment:
MATOMO_DATABASE_HOST: db
MATOMO_DATABASE_ADAPTER: mysql
MATOMO_DATABASE_USERNAME: matomo
MATOMO_DATABASE_PASSWORD: matomo_pw
MATOMO_DATABASE_DBNAME: matomo
volumes:
- matomo_data:/var/www/html
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1/ >/dev/null || exit 1"]
interval: 10s
timeout: 5s
retries: 60
bootstrap:
# This prevents automatic startup during a normal `docker compose up`
profiles: ["bootstrap"]
# Option A: use the published image (recommended)
image: ghcr.io/kevinveenbirkenbach/matomo-bootstrap:1.0.1
# Option B: build locally from the repository checkout
# build:
# context: .
# dockerfile: Dockerfile
# image: matomo-bootstrap:local
container_name: matomo-bootstrap
depends_on:
matomo:
condition: service_started
environment:
# inside the compose network, Matomo is reachable via the service name
MATOMO_URL: "http://matomo"
MATOMO_ADMIN_USER: "administrator"
MATOMO_ADMIN_PASSWORD: "AdminSecret123!"
MATOMO_ADMIN_EMAIL: "administrator@example.org"
MATOMO_TOKEN_DESCRIPTION: "docker-compose-bootstrap"
# Values used by the recorded installer flow
MATOMO_SITE_NAME: "Matomo (docker-compose)"
MATOMO_SITE_URL: "http://127.0.0.1:${MATOMO_PORT:-8080}"
MATOMO_TIMEZONE: "Germany - Berlin"
# Optional stability knobs
MATOMO_TIMEOUT: "30"
MATOMO_PLAYWRIGHT_HEADLESS: "1"
MATOMO_PLAYWRIGHT_NAV_TIMEOUT_MS: "60000"
MATOMO_PLAYWRIGHT_SLOWMO_MS: "0"
restart: "no"
volumes:
mariadb_data:
matomo_data:
```
---
### Commands
Start DB + Matomo **without** bootstrap:
```bash
docker compose up -d db matomo
```
Run bootstrap once (prints token to stdout):
```bash
docker compose --profile bootstrap run --rm bootstrap
```
Re-run bootstrap (creates a new token by default):
```bash
docker compose --profile bootstrap run --rm bootstrap
```
---
## Idempotency / avoiding new tokens on every run
By default, `UsersManager.createAppSpecificTokenAuth` creates a new token each time.
If you want strictly idempotent runs in automation, you can provide an existing token
and make the bootstrap return it instead of creating a new one:
```bash
export MATOMO_BOOTSTRAP_TOKEN_AUTH="0123456789abcdef..."
matomo-bootstrap
```
> This is useful for CI re-runs or configuration management tools.
---
## How it works
1. **Reachability check**
* waits until Matomo responds via HTTP (any status is considered “reachable”)
2. **Installation (if needed)**
* uses a recorded Playwright flow to complete the Matomo web installer
3. **Authentication**
* logs in using Matomos `Login.logme` controller (cookie session)
4. **Token creation**
* calls `UsersManager.createAppSpecificTokenAuth`
5. **Output**
* prints the token to stdout (token-only contract)
---
## End-to-end tests
Run the full E2E cycle locally:
```bash
make e2e
```
This will:
1. Start Matomo + MariaDB via Docker
2. Install Matomo headlessly
3. Create an API token
4. Validate the token via the Matomo API
5. Tear everything down again
---
## Author
**Kevin Veen-Birkenbach**
[https://www.veen.world/](https://www.veen.world/)
---
## License
MIT — see [LICENSE](LICENSE)