Vibecode Matomo Cloud
track this build5 phases, 15 steps, beginner friendly0%The core loop is buildable, but a dependable replacement becomes a real weekend or multi-day project. For Matomo Cloud, run first-party web analytics with goals, campaigns, and user-owned data. The hard boundary is mature analytics depth, privacy controls, hosted operations, and premium plugins, plus data pipeline reliability and analytical depth.
You are building a lean indie version of Matomo Cloud. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== README.md ===== # Matomo Cloud · indie build Build a self-hosted Matomo installation with working archives and recoverable data. Estimated effort: **multi-day**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts. ## Stack | Part | Choice | Why | | --- | --- | --- | | Application | Upstream Matomo container | Reuse the maintained application; the work is deployment and operations. | | Storage | Upstream-compatible MySQL/MariaDB | Use the upstream schema and keep data across container replacement. | | Deployment | Docker Compose; Caddy for product HTTPS | Explicit volumes, ports and configuration can be reviewed and recreated. | ## Before you start Have every one of these ready. The plan assumes them from step one. - [ ] **Docker Engine and Compose v2** · Docker Engine has no hosting fee; Desktop licensing depends on your use, and a rented host is billed separately. - Why: The upstream application runs in containers. - Get it: Install Docker Engine and the Compose plugin on Linux using the official instructions. On Windows use Docker Desktop with WSL2, then work inside a Linux project folder. - Verify: docker compose version prints a v2 version and docker info reaches the daemon. - [ ] **Choose and record the upstream release** · Software/edition terms and optional paid features are defined by the upstream project. - Why: The guide must match the software you actually deploy. - Get it: Open https://matomo.org/faq/on-premise/installing-matomo/, choose a stable release compatible with its database requirements, record its tag and resolved digest in versions.txt, and use those values in compose.yaml. Avoid unattended latest-tag updates. - Verify: versions.txt names both application and database versions or states that the pilot uses embedded SQLite. - [ ] **Matomo Cloud acceptance sample** · No paid service required for this local step. - Why: This fixture makes the first end-to-end check reproducible. - Get it: Create synthetic sample data before implementation: One owned site with a pageview, a campaign-tagged visit and a goal completion. Save it under fixtures/ with the expected results in fixtures/README.md; use no real credentials or customer records. - Verify: The fixture files and expected outcomes exist and can be inspected without a vendor account. - [ ] **Confirm the bounded replacement** · No paid service required for this local step. - Why: The full commercial product is larger than this guide. - Get it: The deliverable is a self-hosted Matomo installation with working archives and recoverable data. Read every exclusion below. Indie mode runs locally; any public or shared use requires the product access and deployment gates first. - Verify: You can name the primary workflow and the vendor features this version deliberately leaves out. ## Quick start ```sh docker compose config --quiet ``` Then copy `.env.example` to `.env` and fill in the values it documents. ## Honest limits This build deliberately does not replace: - This is a self-hosted Matomo installation with working archives and recoverable data; full Matomo Cloud feature parity, vendor hosting and support are not included. - mature analytics depth, privacy controls, hosted operations, and premium plugins - identity stitching - session replay - warehouse connectors - high-volume global ingestion and support If one of those is essential to you, that is the reason to keep paying for Matomo Cloud, and the README should say so rather than pretend. ===== BRIEF.md ===== # Build brief · Matomo Cloud The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a self-hosted Matomo installation with working archives and recoverable data as a bounded replacement for Matomo Cloud. Build it in phases in the order below. Do not write the whole product in one pass. Finish the current phase, run its Done when checks, fix failures, then continue. Indie mode completes Phases 1-5. Phase 6 is required before shared or public deployment. ### Stack (fixed, do not substitute) - Application: Upstream Matomo container. Reuse the maintained application; the work is deployment and operations. - Storage: Upstream-compatible MySQL/MariaDB. Use the upstream schema and keep data across container replacement. - Deployment: Docker Compose; Caddy for product HTTPS. Explicit volumes, ports and configuration can be reviewed and recreated. ### Data model (create this before Phase 1) - Use the upstream Matomo MySQL/MariaDB schema. Back up its database, config/config.ini.php, custom plugin/theme files and the pinned application version together. Keep test site ids and archive-run evidence in OPERATIONS.md. - Use stable ids and explicit relationships; add auxiliary tables named by the phases before those phases use them. - Acceptance fixture: One owned site with a pageview, a campaign-tagged visit and a goal completion. ### Prerequisites and configuration - Docker Engine and Compose v2: Install Docker Engine and the Compose plugin on Linux using the official instructions. On Windows use Docker Desktop with WSL2, then work inside a Linux project folder. Verify: docker compose version prints a v2 version and docker info reaches the daemon. Cost: Docker Engine has no hosting fee; Desktop licensing depends on your use, and a rented host is billed separately. - Choose and record the upstream release: Open https://matomo.org/faq/on-premise/installing-matomo/, choose a stable release compatible with its database requirements, record its tag and resolved digest in versions.txt, and use those values in compose.yaml. Avoid unattended latest-tag updates. Verify: versions.txt names both application and database versions or states that the pilot uses embedded SQLite. Cost: Software/edition terms and optional paid features are defined by the upstream project. - Matomo Cloud acceptance sample: Create synthetic sample data before implementation: One owned site with a pageview, a campaign-tagged visit and a goal completion. Save it under fixtures/ with the expected results in fixtures/README.md; use no real credentials or customer records. Verify: The fixture files and expected outcomes exist and can be inspected without a vendor account. Cost: No paid service required for this local step. - Confirm the bounded replacement: The deliverable is a self-hosted Matomo installation with working archives and recoverable data. Read every exclusion below. Indie mode runs locally; any public or shared use requires the product access and deployment gates first. Verify: You can name the primary workflow and the vendor features this version deliberately leaves out. Cost: No paid service required for this local step. - Configuration: APP_IMAGE, SITE_URL, DB_PASSWORD. Ship .env.example, replace placeholders and exclude secrets from git. ### Phase 1 · Deployment inventory and safe pilot Build: Prepare the pinned upstream deployment for a self-hosted Matomo installation with working archives and recoverable data. - Read the linked upstream installation guide and create compose.yaml, .env.example, versions.txt and OPERATIONS.md. Map APP_IMAGE and only each service's required environment variables explicitly. Keep database ports internal and map the pilot application port to 127.0.0.1. - Use the upstream Matomo MySQL/MariaDB schema. Back up its database, config/config.ini.php, custom plugin/theme files and the pinned application version together. Keep test site ids and archive-run evidence in OPERATIONS.md. Name each volume and its mount path in OPERATIONS.md; never use ephemeral container storage for the only copy. Create .env manually from .env.example and replace placeholders before starting. Commands, after creating the named files: `docker compose config --quiet`. - Create a private fixtures/ folder containing: One owned site with a pageview, a campaign-tagged visit and a goal completion. Create a separate backup destination and an isolated restore-project name; do not reuse live volumes in restore exercises. - Trap: A valid Compose file proves configuration syntax only, not application health. Done when: docker compose config --quiet succeeds with no unresolved required variables. The documented volume list includes every persistent asset and no secret is committed. Do not build yet: Do not start install existing analytics until these checks pass. ### Phase 2 · Install existing analytics Build: Install existing analytics for Matomo Cloud: Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. - Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. - Complete the installer, create the admin and test site and record system-check results before adding tracking. - Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The installer system checks pass and the dashboard opens with the new admin. Then check: A container restart preserves the site configuration and account. Record commands, observed results and the date in OPERATIONS.md. - Trap: The task is operating Matomo, not cloning its tracking pipeline. Done when: The installer system checks pass and the dashboard opens with the new admin. A container restart preserves the site configuration and account. Do not build yet: Do not start collection and archiving until these checks pass. ### Phase 3 · Collection and archiving Build: Collection and archiving for Matomo Cloud: Install the generated tracker on the owned site and configure privacy/retention settings intentionally. - Install the generated tracker on the owned site and configure privacy/retention settings intentionally. - Run the upstream console archive task, schedule it with the documented URL and inspect its exit status and log age. - Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The campaign visit and configured goal appear after a successful archive run. Then check: Breaking database access makes archiving fail visibly instead of updating a false success timestamp. Record commands, observed results and the date in OPERATIONS.md. - Trap: A collecting tracker can coexist with stale reports when the archive job is broken. Done when: The campaign visit and configured goal appear after a successful archive run. Breaking database access makes archiving fail visibly instead of updating a false success timestamp. Do not build yet: Do not start complete backup and restore until these checks pass. ### Phase 4 · Complete backup and restore Build: Complete backup and restore for Matomo Cloud: Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. - Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. - Restore to an isolated installation with outbound tracking disabled and verify the site, goal and reports before planning an update. - Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The restored instance contains the fixture goal and site settings. Then check: Restoring only the database is documented as incomplete because configuration and custom files also matter. Record commands, observed results and the date in OPERATIONS.md. - Trap: Premium plugins and vendor-operated infrastructure are separate from the self-hosted core. Done when: The restored instance contains the fixture goal and site settings. Restoring only the database is documented as incomplete because configuration and custom files also matter. Do not build yet: Do not start portable delivery and clean-start proof until these checks pass. ### Phase 5 · Portable delivery and clean-start proof Build: Finish the Matomo Cloud replacement with a documented first-run path and a recoverable export. - Document prerequisites, every configuration variable, data locations and the three domain workflows: Install existing analytics; Collection and archiving; Complete backup and restore. Include the exclusions, actual costs and source check date 2026-09-05. Commands shown earlier that reference project files are files the builder must implement before running them. - Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. Restore into a separate empty directory or isolated deployment, with all outbound actions and schedules disabled. Recreate this proof: One owned site with a pageview, a campaign-tagged visit and a goal completion. Compare ids/counts and open the result before recording the restore date. Never test a restore over the only live copy. - Use a new folder and only README instructions to reach the fixture outcome. Verify upstream login, persistence, proof output and restore. Record exactly what passed; do not mark unrun checks complete. Commands, after creating the named files: `docker compose ps`. - Trap: Export without an import or restore rehearsal is not verified portability. Done when: A new folder reaches the documented fixture outcome using only README instructions. A backup restored in isolation preserves the proof data and can be opened. Do not build yet: Do not start operate and share with access controls until these checks pass. ### Phase 6 · Operate and share with access controls (product-builder only) Build: Product-builder only: make a self-hosted Matomo installation with working archives and recoverable data operable for its stated audience before allowing remote access. - Use upstream authentication, replace default credentials, restrict the editor/admin surface and inventory public ingestion/webhook paths. Review upstream edition and license boundaries before offering this as a service. - Put Caddy HTTPS in front of the upstream app, keep database and management ports private and configure public URLs from the chosen domain. For n8n, rehearse upstream PostgreSQL migration/import and recovery before claiming production readiness; disable any unused AI sandbox services. - Add a scheduled encrypted off-host backup using this procedure: Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. Monitor health, disk space, failed jobs and backup age. Stop the service to test an alert; rehearse recovery with outbound effects disabled and record recovery time. Rotate any exposed credentials and require reconciliation before resuming queues. - Trap: Product mode is additional engineering, not a switch that makes a local prototype production-ready. Done when: An unauthenticated visitor cannot read private records, download private files or mutate the admin surface. A viewer cannot mutate data by making a direct request, and guessed ids cannot cross ownership boundaries. Stopping the service triggers the configured alert and the latest off-host backup restores the fixture in isolation. Do not build yet: Do not add new providers or vendor-scale features until the release gates are recorded. ### Out of scope (and why) - This is a self-hosted Matomo installation with working archives and recoverable data; full Matomo Cloud feature parity, vendor hosting and support are not included. - mature analytics depth, privacy controls, hosted operations, and premium plugins: retain the paid product if this capability is essential; it is outside this bounded build. - identity stitching: retain the paid product if this capability is essential; it is outside this bounded build. - session replay: retain the paid product if this capability is essential; it is outside this bounded build. - warehouse connectors: retain the paid product if this capability is essential; it is outside this bounded build. - high-volume global ingestion and support: retain the paid product if this capability is essential; it is outside this bounded build. ### README must contain - Exact install, configure, initialize, start, test and recovery commands for a clean folder. - The schema, fixture, acceptance results, private data locations and export format. - Every prerequisite and secret source, actual running costs and deliberately excluded capabilities. - An honest distinction between tests actually run and checks still awaiting real credentials or deployment. - Dependency documentation reviewed 2026-09-05: https://matomo.org/faq/on-premise/installing-matomo/ ; https://matomo.org/faq/on-premise/what-are-the-requirements-and-recommendations-for-matomo-backup/. Recheck before upgrading; freeze the versions actually tested. ===== AGENTS.md ===== # Agent instructions · Matomo Cloud indie build - Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: Upstream Matomo container, Upstream-compatible MySQL/MariaDB, Docker Compose; Caddy for product HTTPS. Do not substitute. - Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes. - Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name. - Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced. - Do not invent cryptography, security guarantees, APIs or compliance claims. - Add a focused test for every destructive, security-sensitive or data-loss path the plan names. - Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs". ## Known traps - A valid Compose file proves configuration syntax only, not application health. - The task is operating Matomo, not cloning its tracking pipeline. - A collecting tracker can coexist with stale reports when the archive job is broken. - Premium plugins and vendor-operated infrastructure are separate from the self-hosted core. - Export without an import or restore rehearsal is not verified portability. ===== BUILD_PLAN.md ===== # Build plan · Matomo Cloud Build a self-hosted Matomo installation with working archives and recoverable data. Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note. ## Phase 1 · Deployment inventory and safe pilot Prepare the pinned upstream deployment for a self-hosted Matomo installation with working archives and recoverable data. ### Steps 1. Create the deployment files Read the linked upstream installation guide and create compose.yaml, .env.example, versions.txt and OPERATIONS.md. Map APP_IMAGE and only each service's required environment variables explicitly. Keep database ports internal and map the pilot application port to 127.0.0.1. Files: `compose.yaml`, `.env.example`, `versions.txt` 2. Identify every persistent asset Use the upstream Matomo MySQL/MariaDB schema. Back up its database, config/config.ini.php, custom plugin/theme files and the pinned application version together. Keep test site ids and archive-run evidence in OPERATIONS.md. Name each volume and its mount path in OPERATIONS.md; never use ephemeral container storage for the only copy. Create .env manually from .env.example and replace placeholders before starting. Files: `OPERATIONS.md`, `.gitignore` ```sh docker compose config --quiet ``` 3. Prepare the proof and recovery folder Create a private fixtures/ folder containing: One owned site with a pageview, a campaign-tagged visit and a goal completion. Create a separate backup destination and an isolated restore-project name; do not reuse live volumes in restore exercises. Files: `fixtures/README.md`, `OPERATIONS.md` ### Done when - [ ] docker compose config --quiet succeeds with no unresolved required variables. - [ ] The documented volume list includes every persistent asset and no secret is committed. ### Watch out - A valid Compose file proves configuration syntax only, not application health. ## Phase 2 · Install existing analytics Install existing analytics for Matomo Cloud: Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. ### Steps 1. Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. Files: `compose.yaml`, `OPERATIONS.md` 2. Complete the installer, create the admin and test site and record system-check results before adding tracking. Complete the installer, create the admin and test site and record system-check results before adding tracking. Files: `OPERATIONS.md` 3. Exercise the acceptance fixture Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The installer system checks pass and the dashboard opens with the new admin. Then check: A container restart preserves the site configuration and account. Record commands, observed results and the date in OPERATIONS.md. Files: `OPERATIONS.md` ### Done when - [ ] The installer system checks pass and the dashboard opens with the new admin. - [ ] A container restart preserves the site configuration and account. ### Watch out - The task is operating Matomo, not cloning its tracking pipeline. ## Phase 3 · Collection and archiving Collection and archiving for Matomo Cloud: Install the generated tracker on the owned site and configure privacy/retention settings intentionally. ### Steps 1. Install the generated tracker on the owned site and configure privacy/retention settings intentionally. Install the generated tracker on the owned site and configure privacy/retention settings intentionally. Files: `compose.yaml`, `OPERATIONS.md` 2. Run the upstream console archive task, schedule it with the documented URL and inspect its exit status and log age. Run the upstream console archive task, schedule it with the documented URL and inspect its exit status and log age. Files: `OPERATIONS.md` 3. Exercise the acceptance fixture Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The campaign visit and configured goal appear after a successful archive run. Then check: Breaking database access makes archiving fail visibly instead of updating a false success timestamp. Record commands, observed results and the date in OPERATIONS.md. Files: `OPERATIONS.md` ### Done when - [ ] The campaign visit and configured goal appear after a successful archive run. - [ ] Breaking database access makes archiving fail visibly instead of updating a false success timestamp. ### Watch out - A collecting tracker can coexist with stale reports when the archive job is broken. ## Phase 4 · Complete backup and restore Complete backup and restore for Matomo Cloud: Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. ### Steps 1. Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. Files: `compose.yaml`, `OPERATIONS.md` 2. Restore to an isolated installation with outbound tracking disabled and verify the site, goal and reports before planning an update. Restore to an isolated installation with outbound tracking disabled and verify the site, goal and reports before planning an update. Files: `OPERATIONS.md` 3. Exercise the acceptance fixture Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The restored instance contains the fixture goal and site settings. Then check: Restoring only the database is documented as incomplete because configuration and custom files also matter. Record commands, observed results and the date in OPERATIONS.md. Files: `OPERATIONS.md` ### Done when - [ ] The restored instance contains the fixture goal and site settings. - [ ] Restoring only the database is documented as incomplete because configuration and custom files also matter. ### Watch out - Premium plugins and vendor-operated infrastructure are separate from the self-hosted core. ## Phase 5 · Portable delivery and clean-start proof Finish the Matomo Cloud replacement with a documented first-run path and a recoverable export. ### Steps 1. Write the user-facing runbook Document prerequisites, every configuration variable, data locations and the three domain workflows: Install existing analytics; Collection and archiving; Complete backup and restore. Include the exclusions, actual costs and source check date 2026-09-05. Commands shown earlier that reference project files are files the builder must implement before running them. Files: `README.md`, `.env.example` 2. Create and rehearse a recoverable backup Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. Restore into a separate empty directory or isolated deployment, with all outbound actions and schedules disabled. Recreate this proof: One owned site with a pageview, a campaign-tagged visit and a goal completion. Compare ids/counts and open the result before recording the restore date. Never test a restore over the only live copy. Files: `OPERATIONS.md`, `backup/README.md` 3. Reproduce the first-run experience Use a new folder and only README instructions to reach the fixture outcome. Verify upstream login, persistence, proof output and restore. Record exactly what passed; do not mark unrun checks complete. Files: `README.md`, `verification.md` ```sh docker compose ps ``` ### Done when - [ ] A new folder reaches the documented fixture outcome using only README instructions. - [ ] A backup restored in isolation preserves the proof data and can be opened. ### Watch out - Export without an import or restore rehearsal is not verified portability. ## Not in this build - This is a self-hosted Matomo installation with working archives and recoverable data; full Matomo Cloud feature parity, vendor hosting and support are not included. - mature analytics depth, privacy controls, hosted operations, and premium plugins - identity stitching - session replay - warehouse connectors - high-volume global ingestion and support ## After v1, if you want it - Extend complete backup and restore only after the fixture and recovery checks pass. - Before adding another integration, document its credentials, limits, cost and failure behavior with primary-source links. ===== .env.example ===== # Copy to .env and fill in. Never commit .env; this file documents it. # Required. Copy the exact application image reference selected from upstream into compose.yaml via this variable. APP_IMAGE=replace-with-tested-image-and-digest # Required. The loopback URL selected in compose.yaml; replace with your HTTPS origin only after completing product deployment. SITE_URL=http://localhost:8080 # Required · secret. Generate a dedicated database password and use it in the database service and Matomo installer; protect config/config.ini.php. DB_PASSWORD=replace-with-random-db-password
You are building a lean indie version of Matomo Cloud. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== README.md ===== # Matomo Cloud · indie build Build a self-hosted Matomo installation with working archives and recoverable data. Estimated effort: **multi-day**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts. ## Stack | Part | Choice | Why | | --- | --- | --- | | Application | Upstream Matomo container | Reuse the maintained application; the work is deployment and operations. | | Storage | Upstream-compatible MySQL/MariaDB | Use the upstream schema and keep data across container replacement. | | Deployment | Docker Compose; Caddy for product HTTPS | Explicit volumes, ports and configuration can be reviewed and recreated. | ## Before you start Have every one of these ready. The plan assumes them from step one. - [ ] **Docker Engine and Compose v2** · Docker Engine has no hosting fee; Desktop licensing depends on your use, and a rented host is billed separately. - Why: The upstream application runs in containers. - Get it: Install Docker Engine and the Compose plugin on Linux using the official instructions. On Windows use Docker Desktop with WSL2, then work inside a Linux project folder. - Verify: docker compose version prints a v2 version and docker info reaches the daemon. - [ ] **Choose and record the upstream release** · Software/edition terms and optional paid features are defined by the upstream project. - Why: The guide must match the software you actually deploy. - Get it: Open https://matomo.org/faq/on-premise/installing-matomo/, choose a stable release compatible with its database requirements, record its tag and resolved digest in versions.txt, and use those values in compose.yaml. Avoid unattended latest-tag updates. - Verify: versions.txt names both application and database versions or states that the pilot uses embedded SQLite. - [ ] **Matomo Cloud acceptance sample** · No paid service required for this local step. - Why: This fixture makes the first end-to-end check reproducible. - Get it: Create synthetic sample data before implementation: One owned site with a pageview, a campaign-tagged visit and a goal completion. Save it under fixtures/ with the expected results in fixtures/README.md; use no real credentials or customer records. - Verify: The fixture files and expected outcomes exist and can be inspected without a vendor account. - [ ] **Confirm the bounded replacement** · No paid service required for this local step. - Why: The full commercial product is larger than this guide. - Get it: The deliverable is a self-hosted Matomo installation with working archives and recoverable data. Read every exclusion below. Indie mode runs locally; any public or shared use requires the product access and deployment gates first. - Verify: You can name the primary workflow and the vendor features this version deliberately leaves out. ## Quick start ```sh docker compose config --quiet ``` Then copy `.env.example` to `.env` and fill in the values it documents. ## Honest limits This build deliberately does not replace: - This is a self-hosted Matomo installation with working archives and recoverable data; full Matomo Cloud feature parity, vendor hosting and support are not included. - mature analytics depth, privacy controls, hosted operations, and premium plugins - identity stitching - session replay - warehouse connectors - high-volume global ingestion and support If one of those is essential to you, that is the reason to keep paying for Matomo Cloud, and the README should say so rather than pretend. ===== BRIEF.md ===== # Build brief · Matomo Cloud The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a self-hosted Matomo installation with working archives and recoverable data as a bounded replacement for Matomo Cloud. Build it in phases in the order below. Do not write the whole product in one pass. Finish the current phase, run its Done when checks, fix failures, then continue. Indie mode completes Phases 1-5. Phase 6 is required before shared or public deployment. ### Stack (fixed, do not substitute) - Application: Upstream Matomo container. Reuse the maintained application; the work is deployment and operations. - Storage: Upstream-compatible MySQL/MariaDB. Use the upstream schema and keep data across container replacement. - Deployment: Docker Compose; Caddy for product HTTPS. Explicit volumes, ports and configuration can be reviewed and recreated. ### Data model (create this before Phase 1) - Use the upstream Matomo MySQL/MariaDB schema. Back up its database, config/config.ini.php, custom plugin/theme files and the pinned application version together. Keep test site ids and archive-run evidence in OPERATIONS.md. - Use stable ids and explicit relationships; add auxiliary tables named by the phases before those phases use them. - Acceptance fixture: One owned site with a pageview, a campaign-tagged visit and a goal completion. ### Prerequisites and configuration - Docker Engine and Compose v2: Install Docker Engine and the Compose plugin on Linux using the official instructions. On Windows use Docker Desktop with WSL2, then work inside a Linux project folder. Verify: docker compose version prints a v2 version and docker info reaches the daemon. Cost: Docker Engine has no hosting fee; Desktop licensing depends on your use, and a rented host is billed separately. - Choose and record the upstream release: Open https://matomo.org/faq/on-premise/installing-matomo/, choose a stable release compatible with its database requirements, record its tag and resolved digest in versions.txt, and use those values in compose.yaml. Avoid unattended latest-tag updates. Verify: versions.txt names both application and database versions or states that the pilot uses embedded SQLite. Cost: Software/edition terms and optional paid features are defined by the upstream project. - Matomo Cloud acceptance sample: Create synthetic sample data before implementation: One owned site with a pageview, a campaign-tagged visit and a goal completion. Save it under fixtures/ with the expected results in fixtures/README.md; use no real credentials or customer records. Verify: The fixture files and expected outcomes exist and can be inspected without a vendor account. Cost: No paid service required for this local step. - Confirm the bounded replacement: The deliverable is a self-hosted Matomo installation with working archives and recoverable data. Read every exclusion below. Indie mode runs locally; any public or shared use requires the product access and deployment gates first. Verify: You can name the primary workflow and the vendor features this version deliberately leaves out. Cost: No paid service required for this local step. - Configuration: APP_IMAGE, SITE_URL, DB_PASSWORD. Ship .env.example, replace placeholders and exclude secrets from git. ### Phase 1 · Deployment inventory and safe pilot Build: Prepare the pinned upstream deployment for a self-hosted Matomo installation with working archives and recoverable data. - Read the linked upstream installation guide and create compose.yaml, .env.example, versions.txt and OPERATIONS.md. Map APP_IMAGE and only each service's required environment variables explicitly. Keep database ports internal and map the pilot application port to 127.0.0.1. - Use the upstream Matomo MySQL/MariaDB schema. Back up its database, config/config.ini.php, custom plugin/theme files and the pinned application version together. Keep test site ids and archive-run evidence in OPERATIONS.md. Name each volume and its mount path in OPERATIONS.md; never use ephemeral container storage for the only copy. Create .env manually from .env.example and replace placeholders before starting. Commands, after creating the named files: `docker compose config --quiet`. - Create a private fixtures/ folder containing: One owned site with a pageview, a campaign-tagged visit and a goal completion. Create a separate backup destination and an isolated restore-project name; do not reuse live volumes in restore exercises. - Trap: A valid Compose file proves configuration syntax only, not application health. Done when: docker compose config --quiet succeeds with no unresolved required variables. The documented volume list includes every persistent asset and no secret is committed. Do not build yet: Do not start install existing analytics until these checks pass. ### Phase 2 · Install existing analytics Build: Install existing analytics for Matomo Cloud: Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. - Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. - Complete the installer, create the admin and test site and record system-check results before adding tracking. - Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The installer system checks pass and the dashboard opens with the new admin. Then check: A container restart preserves the site configuration and account. Record commands, observed results and the date in OPERATIONS.md. - Trap: The task is operating Matomo, not cloning its tracking pipeline. Done when: The installer system checks pass and the dashboard opens with the new admin. A container restart preserves the site configuration and account. Do not build yet: Do not start collection and archiving until these checks pass. ### Phase 3 · Collection and archiving Build: Collection and archiving for Matomo Cloud: Install the generated tracker on the owned site and configure privacy/retention settings intentionally. - Install the generated tracker on the owned site and configure privacy/retention settings intentionally. - Run the upstream console archive task, schedule it with the documented URL and inspect its exit status and log age. - Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The campaign visit and configured goal appear after a successful archive run. Then check: Breaking database access makes archiving fail visibly instead of updating a false success timestamp. Record commands, observed results and the date in OPERATIONS.md. - Trap: A collecting tracker can coexist with stale reports when the archive job is broken. Done when: The campaign visit and configured goal appear after a successful archive run. Breaking database access makes archiving fail visibly instead of updating a false success timestamp. Do not build yet: Do not start complete backup and restore until these checks pass. ### Phase 4 · Complete backup and restore Build: Complete backup and restore for Matomo Cloud: Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. - Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. - Restore to an isolated installation with outbound tracking disabled and verify the site, goal and reports before planning an update. - Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The restored instance contains the fixture goal and site settings. Then check: Restoring only the database is documented as incomplete because configuration and custom files also matter. Record commands, observed results and the date in OPERATIONS.md. - Trap: Premium plugins and vendor-operated infrastructure are separate from the self-hosted core. Done when: The restored instance contains the fixture goal and site settings. Restoring only the database is documented as incomplete because configuration and custom files also matter. Do not build yet: Do not start portable delivery and clean-start proof until these checks pass. ### Phase 5 · Portable delivery and clean-start proof Build: Finish the Matomo Cloud replacement with a documented first-run path and a recoverable export. - Document prerequisites, every configuration variable, data locations and the three domain workflows: Install existing analytics; Collection and archiving; Complete backup and restore. Include the exclusions, actual costs and source check date 2026-09-05. Commands shown earlier that reference project files are files the builder must implement before running them. - Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. Restore into a separate empty directory or isolated deployment, with all outbound actions and schedules disabled. Recreate this proof: One owned site with a pageview, a campaign-tagged visit and a goal completion. Compare ids/counts and open the result before recording the restore date. Never test a restore over the only live copy. - Use a new folder and only README instructions to reach the fixture outcome. Verify upstream login, persistence, proof output and restore. Record exactly what passed; do not mark unrun checks complete. Commands, after creating the named files: `docker compose ps`. - Trap: Export without an import or restore rehearsal is not verified portability. Done when: A new folder reaches the documented fixture outcome using only README instructions. A backup restored in isolation preserves the proof data and can be opened. Do not build yet: Do not start operate and share with access controls until these checks pass. ### Phase 6 · Operate and share with access controls (product-builder only) Build: Product-builder only: make a self-hosted Matomo installation with working archives and recoverable data operable for its stated audience before allowing remote access. - Use upstream authentication, replace default credentials, restrict the editor/admin surface and inventory public ingestion/webhook paths. Review upstream edition and license boundaries before offering this as a service. - Put Caddy HTTPS in front of the upstream app, keep database and management ports private and configure public URLs from the chosen domain. For n8n, rehearse upstream PostgreSQL migration/import and recovery before claiming production readiness; disable any unused AI sandbox services. - Add a scheduled encrypted off-host backup using this procedure: Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. Monitor health, disk space, failed jobs and backup age. Stop the service to test an alert; rehearse recovery with outbound effects disabled and record recovery time. Rotate any exposed credentials and require reconciliation before resuming queues. - Trap: Product mode is additional engineering, not a switch that makes a local prototype production-ready. Done when: An unauthenticated visitor cannot read private records, download private files or mutate the admin surface. A viewer cannot mutate data by making a direct request, and guessed ids cannot cross ownership boundaries. Stopping the service triggers the configured alert and the latest off-host backup restores the fixture in isolation. Do not build yet: Do not add new providers or vendor-scale features until the release gates are recorded. ### Out of scope (and why) - This is a self-hosted Matomo installation with working archives and recoverable data; full Matomo Cloud feature parity, vendor hosting and support are not included. - mature analytics depth, privacy controls, hosted operations, and premium plugins: retain the paid product if this capability is essential; it is outside this bounded build. - identity stitching: retain the paid product if this capability is essential; it is outside this bounded build. - session replay: retain the paid product if this capability is essential; it is outside this bounded build. - warehouse connectors: retain the paid product if this capability is essential; it is outside this bounded build. - high-volume global ingestion and support: retain the paid product if this capability is essential; it is outside this bounded build. ### README must contain - Exact install, configure, initialize, start, test and recovery commands for a clean folder. - The schema, fixture, acceptance results, private data locations and export format. - Every prerequisite and secret source, actual running costs and deliberately excluded capabilities. - An honest distinction between tests actually run and checks still awaiting real credentials or deployment. - Dependency documentation reviewed 2026-09-05: https://matomo.org/faq/on-premise/installing-matomo/ ; https://matomo.org/faq/on-premise/what-are-the-requirements-and-recommendations-for-matomo-backup/. Recheck before upgrading; freeze the versions actually tested. ===== AGENTS.md ===== # Agent instructions · Matomo Cloud indie build - Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: Upstream Matomo container, Upstream-compatible MySQL/MariaDB, Docker Compose; Caddy for product HTTPS. Do not substitute. - Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes. - Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name. - Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced. - Do not invent cryptography, security guarantees, APIs or compliance claims. - Add a focused test for every destructive, security-sensitive or data-loss path the plan names. - Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs". ## Known traps - A valid Compose file proves configuration syntax only, not application health. - The task is operating Matomo, not cloning its tracking pipeline. - A collecting tracker can coexist with stale reports when the archive job is broken. - Premium plugins and vendor-operated infrastructure are separate from the self-hosted core. - Export without an import or restore rehearsal is not verified portability. ===== BUILD_PLAN.md ===== # Build plan · Matomo Cloud Build a self-hosted Matomo installation with working archives and recoverable data. Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note. ## Phase 1 · Deployment inventory and safe pilot Prepare the pinned upstream deployment for a self-hosted Matomo installation with working archives and recoverable data. ### Steps 1. Create the deployment files Read the linked upstream installation guide and create compose.yaml, .env.example, versions.txt and OPERATIONS.md. Map APP_IMAGE and only each service's required environment variables explicitly. Keep database ports internal and map the pilot application port to 127.0.0.1. Files: `compose.yaml`, `.env.example`, `versions.txt` 2. Identify every persistent asset Use the upstream Matomo MySQL/MariaDB schema. Back up its database, config/config.ini.php, custom plugin/theme files and the pinned application version together. Keep test site ids and archive-run evidence in OPERATIONS.md. Name each volume and its mount path in OPERATIONS.md; never use ephemeral container storage for the only copy. Create .env manually from .env.example and replace placeholders before starting. Files: `OPERATIONS.md`, `.gitignore` ```sh docker compose config --quiet ``` 3. Prepare the proof and recovery folder Create a private fixtures/ folder containing: One owned site with a pageview, a campaign-tagged visit and a goal completion. Create a separate backup destination and an isolated restore-project name; do not reuse live volumes in restore exercises. Files: `fixtures/README.md`, `OPERATIONS.md` ### Done when - [ ] docker compose config --quiet succeeds with no unresolved required variables. - [ ] The documented volume list includes every persistent asset and no secret is committed. ### Watch out - A valid Compose file proves configuration syntax only, not application health. ## Phase 2 · Install existing analytics Install existing analytics for Matomo Cloud: Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. ### Steps 1. Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. Files: `compose.yaml`, `OPERATIONS.md` 2. Complete the installer, create the admin and test site and record system-check results before adding tracking. Complete the installer, create the admin and test site and record system-check results before adding tracking. Files: `OPERATIONS.md` 3. Exercise the acceptance fixture Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The installer system checks pass and the dashboard opens with the new admin. Then check: A container restart preserves the site configuration and account. Record commands, observed results and the date in OPERATIONS.md. Files: `OPERATIONS.md` ### Done when - [ ] The installer system checks pass and the dashboard opens with the new admin. - [ ] A container restart preserves the site configuration and account. ### Watch out - The task is operating Matomo, not cloning its tracking pipeline. ## Phase 3 · Collection and archiving Collection and archiving for Matomo Cloud: Install the generated tracker on the owned site and configure privacy/retention settings intentionally. ### Steps 1. Install the generated tracker on the owned site and configure privacy/retention settings intentionally. Install the generated tracker on the owned site and configure privacy/retention settings intentionally. Files: `compose.yaml`, `OPERATIONS.md` 2. Run the upstream console archive task, schedule it with the documented URL and inspect its exit status and log age. Run the upstream console archive task, schedule it with the documented URL and inspect its exit status and log age. Files: `OPERATIONS.md` 3. Exercise the acceptance fixture Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The campaign visit and configured goal appear after a successful archive run. Then check: Breaking database access makes archiving fail visibly instead of updating a false success timestamp. Record commands, observed results and the date in OPERATIONS.md. Files: `OPERATIONS.md` ### Done when - [ ] The campaign visit and configured goal appear after a successful archive run. - [ ] Breaking database access makes archiving fail visibly instead of updating a false success timestamp. ### Watch out - A collecting tracker can coexist with stale reports when the archive job is broken. ## Phase 4 · Complete backup and restore Complete backup and restore for Matomo Cloud: Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. ### Steps 1. Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. Files: `compose.yaml`, `OPERATIONS.md` 2. Restore to an isolated installation with outbound tracking disabled and verify the site, goal and reports before planning an update. Restore to an isolated installation with outbound tracking disabled and verify the site, goal and reports before planning an update. Files: `OPERATIONS.md` 3. Exercise the acceptance fixture Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The restored instance contains the fixture goal and site settings. Then check: Restoring only the database is documented as incomplete because configuration and custom files also matter. Record commands, observed results and the date in OPERATIONS.md. Files: `OPERATIONS.md` ### Done when - [ ] The restored instance contains the fixture goal and site settings. - [ ] Restoring only the database is documented as incomplete because configuration and custom files also matter. ### Watch out - Premium plugins and vendor-operated infrastructure are separate from the self-hosted core. ## Phase 5 · Portable delivery and clean-start proof Finish the Matomo Cloud replacement with a documented first-run path and a recoverable export. ### Steps 1. Write the user-facing runbook Document prerequisites, every configuration variable, data locations and the three domain workflows: Install existing analytics; Collection and archiving; Complete backup and restore. Include the exclusions, actual costs and source check date 2026-09-05. Commands shown earlier that reference project files are files the builder must implement before running them. Files: `README.md`, `.env.example` 2. Create and rehearse a recoverable backup Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. Restore into a separate empty directory or isolated deployment, with all outbound actions and schedules disabled. Recreate this proof: One owned site with a pageview, a campaign-tagged visit and a goal completion. Compare ids/counts and open the result before recording the restore date. Never test a restore over the only live copy. Files: `OPERATIONS.md`, `backup/README.md` 3. Reproduce the first-run experience Use a new folder and only README instructions to reach the fixture outcome. Verify upstream login, persistence, proof output and restore. Record exactly what passed; do not mark unrun checks complete. Files: `README.md`, `verification.md` ```sh docker compose ps ``` ### Done when - [ ] A new folder reaches the documented fixture outcome using only README instructions. - [ ] A backup restored in isolation preserves the proof data and can be opened. ### Watch out - Export without an import or restore rehearsal is not verified portability. ## Not in this build - This is a self-hosted Matomo installation with working archives and recoverable data; full Matomo Cloud feature parity, vendor hosting and support are not included. - mature analytics depth, privacy controls, hosted operations, and premium plugins - identity stitching - session replay - warehouse connectors - high-volume global ingestion and support ## After v1, if you want it - Extend complete backup and restore only after the fixture and recovery checks pass. - Before adding another integration, document its credentials, limits, cost and failure behavior with primary-source links. ===== .env.example ===== # Copy to .env and fill in. Never commit .env; this file documents it. # Required. Copy the exact application image reference selected from upstream into compose.yaml via this variable. APP_IMAGE=replace-with-tested-image-and-digest # Required. The loopback URL selected in compose.yaml; replace with your HTTPS origin only after completing product deployment. SITE_URL=http://localhost:8080 # Required · secret. Generate a dedicated database password and use it in the database service and Matomo installer; protect config/config.ini.php. DB_PASSWORD=replace-with-random-db-password
You are building a production product version of Matomo Cloud. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== PRODUCT.md ===== # Matomo Cloud · product brief ## Problem The core loop is buildable, but a dependable replacement becomes a real weekend or multi-day project. For Matomo Cloud, run first-party web analytics with goals, campaigns, and user-owned data. The hard boundary is mature analytics depth, privacy controls, hosted operations, and premium plugins, plus data pipeline reliability and analytical depth. ## Product outcome An operated version of a self-hosted Matomo installation with working archives and recoverable data, with authorized access, restore evidence and honest scope limits. ## Target user A builder who needs a maintainable product foundation, not a one-off demo. ## Required capabilities - Docker - ClickHouse - PostgreSQL - public HTTPS collector endpoint - site script access ## Explicit non-goals for v1 - This is a self-hosted Matomo installation with working archives and recoverable data; full Matomo Cloud feature parity, vendor hosting and support are not included. - mature analytics depth, privacy controls, hosted operations, and premium plugins - identity stitching - session replay - warehouse connectors - high-volume global ingestion and support ## Success criteria - The installer system checks pass and the dashboard opens with the new admin. - The campaign visit and configured goal appear after a successful archive run. - The restored instance contains the fixture goal and site settings. - A private-data authorization check passes using a second identity. - An off-host restore drill has a date, observed result and recovery time in OPERATIONS.md. - README names the excluded vendor capabilities and actual provider/hosting costs. ===== BRIEF.md ===== # Build brief · Matomo Cloud The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a self-hosted Matomo installation with working archives and recoverable data as a bounded replacement for Matomo Cloud. Build it in phases in the order below. Do not write the whole product in one pass. Finish the current phase, run its Done when checks, fix failures, then continue. Indie mode completes Phases 1-5. Phase 6 is required before shared or public deployment. ### Stack (fixed, do not substitute) - Application: Upstream Matomo container. Reuse the maintained application; the work is deployment and operations. - Storage: Upstream-compatible MySQL/MariaDB. Use the upstream schema and keep data across container replacement. - Deployment: Docker Compose; Caddy for product HTTPS. Explicit volumes, ports and configuration can be reviewed and recreated. ### Data model (create this before Phase 1) - Use the upstream Matomo MySQL/MariaDB schema. Back up its database, config/config.ini.php, custom plugin/theme files and the pinned application version together. Keep test site ids and archive-run evidence in OPERATIONS.md. - Use stable ids and explicit relationships; add auxiliary tables named by the phases before those phases use them. - Acceptance fixture: One owned site with a pageview, a campaign-tagged visit and a goal completion. ### Prerequisites and configuration - Docker Engine and Compose v2: Install Docker Engine and the Compose plugin on Linux using the official instructions. On Windows use Docker Desktop with WSL2, then work inside a Linux project folder. Verify: docker compose version prints a v2 version and docker info reaches the daemon. Cost: Docker Engine has no hosting fee; Desktop licensing depends on your use, and a rented host is billed separately. - Choose and record the upstream release: Open https://matomo.org/faq/on-premise/installing-matomo/, choose a stable release compatible with its database requirements, record its tag and resolved digest in versions.txt, and use those values in compose.yaml. Avoid unattended latest-tag updates. Verify: versions.txt names both application and database versions or states that the pilot uses embedded SQLite. Cost: Software/edition terms and optional paid features are defined by the upstream project. - Matomo Cloud acceptance sample: Create synthetic sample data before implementation: One owned site with a pageview, a campaign-tagged visit and a goal completion. Save it under fixtures/ with the expected results in fixtures/README.md; use no real credentials or customer records. Verify: The fixture files and expected outcomes exist and can be inspected without a vendor account. Cost: No paid service required for this local step. - Confirm the bounded replacement: The deliverable is a self-hosted Matomo installation with working archives and recoverable data. Read every exclusion below. Indie mode runs locally; any public or shared use requires the product access and deployment gates first. Verify: You can name the primary workflow and the vendor features this version deliberately leaves out. Cost: No paid service required for this local step. - Configuration: APP_IMAGE, SITE_URL, DB_PASSWORD. Ship .env.example, replace placeholders and exclude secrets from git. ### Phase 1 · Deployment inventory and safe pilot Build: Prepare the pinned upstream deployment for a self-hosted Matomo installation with working archives and recoverable data. - Read the linked upstream installation guide and create compose.yaml, .env.example, versions.txt and OPERATIONS.md. Map APP_IMAGE and only each service's required environment variables explicitly. Keep database ports internal and map the pilot application port to 127.0.0.1. - Use the upstream Matomo MySQL/MariaDB schema. Back up its database, config/config.ini.php, custom plugin/theme files and the pinned application version together. Keep test site ids and archive-run evidence in OPERATIONS.md. Name each volume and its mount path in OPERATIONS.md; never use ephemeral container storage for the only copy. Create .env manually from .env.example and replace placeholders before starting. Commands, after creating the named files: `docker compose config --quiet`. - Create a private fixtures/ folder containing: One owned site with a pageview, a campaign-tagged visit and a goal completion. Create a separate backup destination and an isolated restore-project name; do not reuse live volumes in restore exercises. - Trap: A valid Compose file proves configuration syntax only, not application health. Done when: docker compose config --quiet succeeds with no unresolved required variables. The documented volume list includes every persistent asset and no secret is committed. Do not build yet: Do not start install existing analytics until these checks pass. ### Phase 2 · Install existing analytics Build: Install existing analytics for Matomo Cloud: Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. - Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. - Complete the installer, create the admin and test site and record system-check results before adding tracking. - Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The installer system checks pass and the dashboard opens with the new admin. Then check: A container restart preserves the site configuration and account. Record commands, observed results and the date in OPERATIONS.md. - Trap: The task is operating Matomo, not cloning its tracking pipeline. Done when: The installer system checks pass and the dashboard opens with the new admin. A container restart preserves the site configuration and account. Do not build yet: Do not start collection and archiving until these checks pass. ### Phase 3 · Collection and archiving Build: Collection and archiving for Matomo Cloud: Install the generated tracker on the owned site and configure privacy/retention settings intentionally. - Install the generated tracker on the owned site and configure privacy/retention settings intentionally. - Run the upstream console archive task, schedule it with the documented URL and inspect its exit status and log age. - Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The campaign visit and configured goal appear after a successful archive run. Then check: Breaking database access makes archiving fail visibly instead of updating a false success timestamp. Record commands, observed results and the date in OPERATIONS.md. - Trap: A collecting tracker can coexist with stale reports when the archive job is broken. Done when: The campaign visit and configured goal appear after a successful archive run. Breaking database access makes archiving fail visibly instead of updating a false success timestamp. Do not build yet: Do not start complete backup and restore until these checks pass. ### Phase 4 · Complete backup and restore Build: Complete backup and restore for Matomo Cloud: Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. - Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. - Restore to an isolated installation with outbound tracking disabled and verify the site, goal and reports before planning an update. - Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The restored instance contains the fixture goal and site settings. Then check: Restoring only the database is documented as incomplete because configuration and custom files also matter. Record commands, observed results and the date in OPERATIONS.md. - Trap: Premium plugins and vendor-operated infrastructure are separate from the self-hosted core. Done when: The restored instance contains the fixture goal and site settings. Restoring only the database is documented as incomplete because configuration and custom files also matter. Do not build yet: Do not start portable delivery and clean-start proof until these checks pass. ### Phase 5 · Portable delivery and clean-start proof Build: Finish the Matomo Cloud replacement with a documented first-run path and a recoverable export. - Document prerequisites, every configuration variable, data locations and the three domain workflows: Install existing analytics; Collection and archiving; Complete backup and restore. Include the exclusions, actual costs and source check date 2026-09-05. Commands shown earlier that reference project files are files the builder must implement before running them. - Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. Restore into a separate empty directory or isolated deployment, with all outbound actions and schedules disabled. Recreate this proof: One owned site with a pageview, a campaign-tagged visit and a goal completion. Compare ids/counts and open the result before recording the restore date. Never test a restore over the only live copy. - Use a new folder and only README instructions to reach the fixture outcome. Verify upstream login, persistence, proof output and restore. Record exactly what passed; do not mark unrun checks complete. Commands, after creating the named files: `docker compose ps`. - Trap: Export without an import or restore rehearsal is not verified portability. Done when: A new folder reaches the documented fixture outcome using only README instructions. A backup restored in isolation preserves the proof data and can be opened. Do not build yet: Do not start operate and share with access controls until these checks pass. ### Phase 6 · Operate and share with access controls (product-builder only) Build: Product-builder only: make a self-hosted Matomo installation with working archives and recoverable data operable for its stated audience before allowing remote access. - Use upstream authentication, replace default credentials, restrict the editor/admin surface and inventory public ingestion/webhook paths. Review upstream edition and license boundaries before offering this as a service. - Put Caddy HTTPS in front of the upstream app, keep database and management ports private and configure public URLs from the chosen domain. For n8n, rehearse upstream PostgreSQL migration/import and recovery before claiming production readiness; disable any unused AI sandbox services. - Add a scheduled encrypted off-host backup using this procedure: Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. Monitor health, disk space, failed jobs and backup age. Stop the service to test an alert; rehearse recovery with outbound effects disabled and record recovery time. Rotate any exposed credentials and require reconciliation before resuming queues. - Trap: Product mode is additional engineering, not a switch that makes a local prototype production-ready. Done when: An unauthenticated visitor cannot read private records, download private files or mutate the admin surface. A viewer cannot mutate data by making a direct request, and guessed ids cannot cross ownership boundaries. Stopping the service triggers the configured alert and the latest off-host backup restores the fixture in isolation. Do not build yet: Do not add new providers or vendor-scale features until the release gates are recorded. ### Out of scope (and why) - This is a self-hosted Matomo installation with working archives and recoverable data; full Matomo Cloud feature parity, vendor hosting and support are not included. - mature analytics depth, privacy controls, hosted operations, and premium plugins: retain the paid product if this capability is essential; it is outside this bounded build. - identity stitching: retain the paid product if this capability is essential; it is outside this bounded build. - session replay: retain the paid product if this capability is essential; it is outside this bounded build. - warehouse connectors: retain the paid product if this capability is essential; it is outside this bounded build. - high-volume global ingestion and support: retain the paid product if this capability is essential; it is outside this bounded build. ### README must contain - Exact install, configure, initialize, start, test and recovery commands for a clean folder. - The schema, fixture, acceptance results, private data locations and export format. - Every prerequisite and secret source, actual running costs and deliberately excluded capabilities. - An honest distinction between tests actually run and checks still awaiting real credentials or deployment. - Dependency documentation reviewed 2026-09-05: https://matomo.org/faq/on-premise/installing-matomo/ ; https://matomo.org/faq/on-premise/what-are-the-requirements-and-recommendations-for-matomo-backup/. Recheck before upgrading; freeze the versions actually tested. ===== ARCHITECTURE.md ===== # Architecture · Matomo Cloud ## Stack | Part | Choice | Why | | --- | --- | --- | | Application | Upstream Matomo container | Reuse the maintained application; the work is deployment and operations. | | Storage | Upstream-compatible MySQL/MariaDB | Use the upstream schema and keep data across container replacement. | | Deployment | Docker Compose; Caddy for product HTTPS | Explicit volumes, ports and configuration can be reviewed and recreated. | ## Modules Each module has one owner concern and a documented way to replace it. | Module | Owns | How to replace it | | --- | --- | --- | | Data and identity | Use the upstream Matomo MySQL/MariaDB schema. Back up its database, config/config.ini.php, custom plugin/theme files and the pinned application version together. Keep test site ids and archive-run evidence in OPERATIONS.md. | Follow upstream migration procedures and verify a restored fixture before switching stores. | | Install existing analytics | Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. | Keep the acceptance contract: The installer system checks pass and the dashboard opens with the new admin. Replace only this module after replaying its fixture; preserve ids and existing records. | | Collection and archiving | Install the generated tracker on the owned site and configure privacy/retention settings intentionally. | Keep the acceptance contract: The campaign visit and configured goal appear after a successful archive run. Replace only this module after replaying its fixture; preserve ids and existing records. | | Complete backup and restore | Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. | Keep the acceptance contract: The restored instance contains the fixture goal and site settings. Replace only this module after replaying its fixture; preserve ids and existing records. | | Operations | Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. | Change host or backup destination only after an isolated restore and authorization check. | ## Configuration Every runtime setting is an environment variable documented in `.env.example`, validated at startup, with a safe local default wherever one exists. - `APP_IMAGE` · required · Copy the exact application image reference selected from upstream into compose.yaml via this variable. - `SITE_URL` · required · The loopback URL selected in compose.yaml; replace with your HTTPS origin only after completing product deployment. - `DB_PASSWORD` · required, secret · Generate a dedicated database password and use it in the database service and Matomo installer; protect config/config.ini.php. ## Production baseline - Security: least privilege, input validation at every boundary, secret redaction in logs, rate limits on abuse-prone paths, no invented security primitives. - Data: explicit schema and migrations, transactional writes where integrity matters, backup and restore procedures that have been exercised. - Integrations: adapters around third-party providers, idempotent webhook or job processing, bounded retries, timeouts. - Observability: structured logs with request or operation ids, an error-tracking hook, and health and readiness checks where a server exists. - Quality: unit tests for domain rules, integration tests at module boundaries, one end-to-end test of the critical path. ## Decision records For each dependency in the stack table, keep a short note: why it was chosen, its failure mode, and how it is replaced. Do not add infrastructure until a requirement in `PRODUCT.md` justifies it. ===== AGENTS.md ===== # Agent instructions · Matomo Cloud product build - Read `PRODUCT.md` and `ARCHITECTURE.md` before changing code. The stack is fixed: Upstream Matomo container, Upstream-compatible MySQL/MariaDB, Docker Compose; Caddy for product HTTPS. - Implement milestone by milestone from `MILESTONES.md`; keep each change reviewable and leave the application runnable at every commit. - Treat authentication, payments, encryption, imports, webhooks and destructive actions as high-risk boundaries when present. - Never invent cryptography or silently weaken a requirement to make a check pass. - Put every external service behind an interface with a deterministic fake for tests. - Add migrations and rollback or recovery notes for every persistent data change. - Log useful operational context without credentials, tokens, passwords or personal data. - Update documentation and run every check before completing a milestone. ## Known traps - A valid Compose file proves configuration syntax only, not application health. - The task is operating Matomo, not cloning its tracking pipeline. - A collecting tracker can coexist with stale reports when the archive job is broken. - Premium plugins and vendor-operated infrastructure are separate from the self-hosted core. - Export without an import or restore rehearsal is not verified portability. - Product mode is additional engineering, not a switch that makes a local prototype production-ready. ===== MILESTONES.md ===== # Delivery milestones · Matomo Cloud Estimated effort: **multi-day** for the indie phases; the production-only milestones add the trust and operability layer. ## M1 · Deployment inventory and safe pilot Prepare the pinned upstream deployment for a self-hosted Matomo installation with working archives and recoverable data. ### Steps 1. Create the deployment files Read the linked upstream installation guide and create compose.yaml, .env.example, versions.txt and OPERATIONS.md. Map APP_IMAGE and only each service's required environment variables explicitly. Keep database ports internal and map the pilot application port to 127.0.0.1. Files: `compose.yaml`, `.env.example`, `versions.txt` 2. Identify every persistent asset Use the upstream Matomo MySQL/MariaDB schema. Back up its database, config/config.ini.php, custom plugin/theme files and the pinned application version together. Keep test site ids and archive-run evidence in OPERATIONS.md. Name each volume and its mount path in OPERATIONS.md; never use ephemeral container storage for the only copy. Create .env manually from .env.example and replace placeholders before starting. Files: `OPERATIONS.md`, `.gitignore` ```sh docker compose config --quiet ``` 3. Prepare the proof and recovery folder Create a private fixtures/ folder containing: One owned site with a pageview, a campaign-tagged visit and a goal completion. Create a separate backup destination and an isolated restore-project name; do not reuse live volumes in restore exercises. Files: `fixtures/README.md`, `OPERATIONS.md` ### Done when - [ ] docker compose config --quiet succeeds with no unresolved required variables. - [ ] The documented volume list includes every persistent asset and no secret is committed. ### Watch out - A valid Compose file proves configuration syntax only, not application health. ## M2 · Install existing analytics Install existing analytics for Matomo Cloud: Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. ### Steps 1. Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. Files: `compose.yaml`, `OPERATIONS.md` 2. Complete the installer, create the admin and test site and record system-check results before adding tracking. Complete the installer, create the admin and test site and record system-check results before adding tracking. Files: `OPERATIONS.md` 3. Exercise the acceptance fixture Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The installer system checks pass and the dashboard opens with the new admin. Then check: A container restart preserves the site configuration and account. Record commands, observed results and the date in OPERATIONS.md. Files: `OPERATIONS.md` ### Done when - [ ] The installer system checks pass and the dashboard opens with the new admin. - [ ] A container restart preserves the site configuration and account. ### Watch out - The task is operating Matomo, not cloning its tracking pipeline. ## M3 · Collection and archiving Collection and archiving for Matomo Cloud: Install the generated tracker on the owned site and configure privacy/retention settings intentionally. ### Steps 1. Install the generated tracker on the owned site and configure privacy/retention settings intentionally. Install the generated tracker on the owned site and configure privacy/retention settings intentionally. Files: `compose.yaml`, `OPERATIONS.md` 2. Run the upstream console archive task, schedule it with the documented URL and inspect its exit status and log age. Run the upstream console archive task, schedule it with the documented URL and inspect its exit status and log age. Files: `OPERATIONS.md` 3. Exercise the acceptance fixture Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The campaign visit and configured goal appear after a successful archive run. Then check: Breaking database access makes archiving fail visibly instead of updating a false success timestamp. Record commands, observed results and the date in OPERATIONS.md. Files: `OPERATIONS.md` ### Done when - [ ] The campaign visit and configured goal appear after a successful archive run. - [ ] Breaking database access makes archiving fail visibly instead of updating a false success timestamp. ### Watch out - A collecting tracker can coexist with stale reports when the archive job is broken. ## M4 · Complete backup and restore Complete backup and restore for Matomo Cloud: Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. ### Steps 1. Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. Files: `compose.yaml`, `OPERATIONS.md` 2. Restore to an isolated installation with outbound tracking disabled and verify the site, goal and reports before planning an update. Restore to an isolated installation with outbound tracking disabled and verify the site, goal and reports before planning an update. Files: `OPERATIONS.md` 3. Exercise the acceptance fixture Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The restored instance contains the fixture goal and site settings. Then check: Restoring only the database is documented as incomplete because configuration and custom files also matter. Record commands, observed results and the date in OPERATIONS.md. Files: `OPERATIONS.md` ### Done when - [ ] The restored instance contains the fixture goal and site settings. - [ ] Restoring only the database is documented as incomplete because configuration and custom files also matter. ### Watch out - Premium plugins and vendor-operated infrastructure are separate from the self-hosted core. ## M5 · Portable delivery and clean-start proof Finish the Matomo Cloud replacement with a documented first-run path and a recoverable export. ### Steps 1. Write the user-facing runbook Document prerequisites, every configuration variable, data locations and the three domain workflows: Install existing analytics; Collection and archiving; Complete backup and restore. Include the exclusions, actual costs and source check date 2026-09-05. Commands shown earlier that reference project files are files the builder must implement before running them. Files: `README.md`, `.env.example` 2. Create and rehearse a recoverable backup Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. Restore into a separate empty directory or isolated deployment, with all outbound actions and schedules disabled. Recreate this proof: One owned site with a pageview, a campaign-tagged visit and a goal completion. Compare ids/counts and open the result before recording the restore date. Never test a restore over the only live copy. Files: `OPERATIONS.md`, `backup/README.md` 3. Reproduce the first-run experience Use a new folder and only README instructions to reach the fixture outcome. Verify upstream login, persistence, proof output and restore. Record exactly what passed; do not mark unrun checks complete. Files: `README.md`, `verification.md` ```sh docker compose ps ``` ### Done when - [ ] A new folder reaches the documented fixture outcome using only README instructions. - [ ] A backup restored in isolation preserves the proof data and can be opened. ### Watch out - Export without an import or restore rehearsal is not verified portability. ## M6 · Operate and share with access controls (production only) Product-builder only: make a self-hosted Matomo installation with working archives and recoverable data operable for its stated audience before allowing remote access. ### Steps 1. Establish owner access before exposure Use upstream authentication, replace default credentials, restrict the editor/admin surface and inventory public ingestion/webhook paths. Review upstream edition and license boundaries before offering this as a service. Files: `ARCHITECTURE.md`, `OPERATIONS.md` 2. Deploy a monitored service Put Caddy HTTPS in front of the upstream app, keep database and management ports private and configure public URLs from the chosen domain. For n8n, rehearse upstream PostgreSQL migration/import and recovery before claiming production readiness; disable any unused AI sandbox services. Files: `Caddyfile`, `OPERATIONS.md` 3. Rehearse loss and recovery Add a scheduled encrypted off-host backup using this procedure: Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. Monitor health, disk space, failed jobs and backup age. Stop the service to test an alert; rehearse recovery with outbound effects disabled and record recovery time. Rotate any exposed credentials and require reconciliation before resuming queues. Files: `OPERATIONS.md`, `release-checklist.md` ### Done when - [ ] An unauthenticated visitor cannot read private records, download private files or mutate the admin surface. - [ ] A viewer cannot mutate data by making a direct request, and guessed ids cannot cross ownership boundaries. - [ ] Stopping the service triggers the configured alert and the latest off-host backup restores the fixture in isolation. ### Watch out - Product mode is additional engineering, not a switch that makes a local prototype production-ready. ===== OPERATIONS.md ===== # Operations · Matomo Cloud ## Backup Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. ## Restore Restore into a separate empty directory or isolated deployment, with all outbound actions and schedules disabled. Recreate this proof: One owned site with a pageview, a campaign-tagged visit and a goal completion. Compare ids/counts and open the result before recording the restore date. Never test a restore over the only live copy. Do a restore drill before the first real user, and write the date here when it passes. ## Monitoring Check HTTP availability, free disk, backup age and domain failures for Install existing analytics, Collection and archiving, Complete backup and restore. Alert without logging private payloads. ## Incident checklist Pause outbound jobs and public intake as appropriate, preserve redacted diagnostics, restore an isolated verified backup, rotate affected credentials and reconcile uncertain effects before reopening. 1. Contain the issue without destroying evidence or user data. 2. Record the timeline and affected scope. 3. Rotate exposed secrets and revoke compromised sessions or credentials. 4. Restore from a verified backup when needed. 5. Document the root cause, the remediation and the regression test. ## Release gate - [ ] The installer system checks pass and the dashboard opens with the new admin. - [ ] The campaign visit and configured goal appear after a successful archive run. - [ ] The restored instance contains the fixture goal and site settings. - [ ] A private-data authorization check passes using a second identity. - [ ] An off-host restore drill has a date, observed result and recovery time in OPERATIONS.md. - [ ] README names the excluded vendor capabilities and actual provider/hosting costs. ## Launch constraint Do not market omitted Matomo Cloud capabilities as implemented. The non-goals in `PRODUCT.md` remain user-visible limitations until they are deliberately delivered. ===== .env.example ===== # Copy to .env and fill in. Never commit .env; this file documents it. # Required. Copy the exact application image reference selected from upstream into compose.yaml via this variable. APP_IMAGE=replace-with-tested-image-and-digest # Required. The loopback URL selected in compose.yaml; replace with your HTTPS origin only after completing product deployment. SITE_URL=http://localhost:8080 # Required · secret. Generate a dedicated database password and use it in the database service and Matomo installer; protect config/config.ini.php. DB_PASSWORD=replace-with-random-db-password
# Matomo Cloud · indie build Build a self-hosted Matomo installation with working archives and recoverable data. Estimated effort: **multi-day**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts. ## Stack | Part | Choice | Why | | --- | --- | --- | | Application | Upstream Matomo container | Reuse the maintained application; the work is deployment and operations. | | Storage | Upstream-compatible MySQL/MariaDB | Use the upstream schema and keep data across container replacement. | | Deployment | Docker Compose; Caddy for product HTTPS | Explicit volumes, ports and configuration can be reviewed and recreated. | ## Before you start Have every one of these ready. The plan assumes them from step one. - [ ] **Docker Engine and Compose v2** · Docker Engine has no hosting fee; Desktop licensing depends on your use, and a rented host is billed separately. - Why: The upstream application runs in containers. - Get it: Install Docker Engine and the Compose plugin on Linux using the official instructions. On Windows use Docker Desktop with WSL2, then work inside a Linux project folder. - Verify: docker compose version prints a v2 version and docker info reaches the daemon. - [ ] **Choose and record the upstream release** · Software/edition terms and optional paid features are defined by the upstream project. - Why: The guide must match the software you actually deploy. - Get it: Open https://matomo.org/faq/on-premise/installing-matomo/, choose a stable release compatible with its database requirements, record its tag and resolved digest in versions.txt, and use those values in compose.yaml. Avoid unattended latest-tag updates. - Verify: versions.txt names both application and database versions or states that the pilot uses embedded SQLite. - [ ] **Matomo Cloud acceptance sample** · No paid service required for this local step. - Why: This fixture makes the first end-to-end check reproducible. - Get it: Create synthetic sample data before implementation: One owned site with a pageview, a campaign-tagged visit and a goal completion. Save it under fixtures/ with the expected results in fixtures/README.md; use no real credentials or customer records. - Verify: The fixture files and expected outcomes exist and can be inspected without a vendor account. - [ ] **Confirm the bounded replacement** · No paid service required for this local step. - Why: The full commercial product is larger than this guide. - Get it: The deliverable is a self-hosted Matomo installation with working archives and recoverable data. Read every exclusion below. Indie mode runs locally; any public or shared use requires the product access and deployment gates first. - Verify: You can name the primary workflow and the vendor features this version deliberately leaves out. ## Quick start ```sh docker compose config --quiet ``` Then copy `.env.example` to `.env` and fill in the values it documents. ## Honest limits This build deliberately does not replace: - This is a self-hosted Matomo installation with working archives and recoverable data; full Matomo Cloud feature parity, vendor hosting and support are not included. - mature analytics depth, privacy controls, hosted operations, and premium plugins - identity stitching - session replay - warehouse connectors - high-volume global ingestion and support If one of those is essential to you, that is the reason to keep paying for Matomo Cloud, and the README should say so rather than pretend.
# Build brief · Matomo Cloud The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a self-hosted Matomo installation with working archives and recoverable data as a bounded replacement for Matomo Cloud. Build it in phases in the order below. Do not write the whole product in one pass. Finish the current phase, run its Done when checks, fix failures, then continue. Indie mode completes Phases 1-5. Phase 6 is required before shared or public deployment. ### Stack (fixed, do not substitute) - Application: Upstream Matomo container. Reuse the maintained application; the work is deployment and operations. - Storage: Upstream-compatible MySQL/MariaDB. Use the upstream schema and keep data across container replacement. - Deployment: Docker Compose; Caddy for product HTTPS. Explicit volumes, ports and configuration can be reviewed and recreated. ### Data model (create this before Phase 1) - Use the upstream Matomo MySQL/MariaDB schema. Back up its database, config/config.ini.php, custom plugin/theme files and the pinned application version together. Keep test site ids and archive-run evidence in OPERATIONS.md. - Use stable ids and explicit relationships; add auxiliary tables named by the phases before those phases use them. - Acceptance fixture: One owned site with a pageview, a campaign-tagged visit and a goal completion. ### Prerequisites and configuration - Docker Engine and Compose v2: Install Docker Engine and the Compose plugin on Linux using the official instructions. On Windows use Docker Desktop with WSL2, then work inside a Linux project folder. Verify: docker compose version prints a v2 version and docker info reaches the daemon. Cost: Docker Engine has no hosting fee; Desktop licensing depends on your use, and a rented host is billed separately. - Choose and record the upstream release: Open https://matomo.org/faq/on-premise/installing-matomo/, choose a stable release compatible with its database requirements, record its tag and resolved digest in versions.txt, and use those values in compose.yaml. Avoid unattended latest-tag updates. Verify: versions.txt names both application and database versions or states that the pilot uses embedded SQLite. Cost: Software/edition terms and optional paid features are defined by the upstream project. - Matomo Cloud acceptance sample: Create synthetic sample data before implementation: One owned site with a pageview, a campaign-tagged visit and a goal completion. Save it under fixtures/ with the expected results in fixtures/README.md; use no real credentials or customer records. Verify: The fixture files and expected outcomes exist and can be inspected without a vendor account. Cost: No paid service required for this local step. - Confirm the bounded replacement: The deliverable is a self-hosted Matomo installation with working archives and recoverable data. Read every exclusion below. Indie mode runs locally; any public or shared use requires the product access and deployment gates first. Verify: You can name the primary workflow and the vendor features this version deliberately leaves out. Cost: No paid service required for this local step. - Configuration: APP_IMAGE, SITE_URL, DB_PASSWORD. Ship .env.example, replace placeholders and exclude secrets from git. ### Phase 1 · Deployment inventory and safe pilot Build: Prepare the pinned upstream deployment for a self-hosted Matomo installation with working archives and recoverable data. - Read the linked upstream installation guide and create compose.yaml, .env.example, versions.txt and OPERATIONS.md. Map APP_IMAGE and only each service's required environment variables explicitly. Keep database ports internal and map the pilot application port to 127.0.0.1. - Use the upstream Matomo MySQL/MariaDB schema. Back up its database, config/config.ini.php, custom plugin/theme files and the pinned application version together. Keep test site ids and archive-run evidence in OPERATIONS.md. Name each volume and its mount path in OPERATIONS.md; never use ephemeral container storage for the only copy. Create .env manually from .env.example and replace placeholders before starting. Commands, after creating the named files: `docker compose config --quiet`. - Create a private fixtures/ folder containing: One owned site with a pageview, a campaign-tagged visit and a goal completion. Create a separate backup destination and an isolated restore-project name; do not reuse live volumes in restore exercises. - Trap: A valid Compose file proves configuration syntax only, not application health. Done when: docker compose config --quiet succeeds with no unresolved required variables. The documented volume list includes every persistent asset and no secret is committed. Do not build yet: Do not start install existing analytics until these checks pass. ### Phase 2 · Install existing analytics Build: Install existing analytics for Matomo Cloud: Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. - Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. - Complete the installer, create the admin and test site and record system-check results before adding tracking. - Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The installer system checks pass and the dashboard opens with the new admin. Then check: A container restart preserves the site configuration and account. Record commands, observed results and the date in OPERATIONS.md. - Trap: The task is operating Matomo, not cloning its tracking pipeline. Done when: The installer system checks pass and the dashboard opens with the new admin. A container restart preserves the site configuration and account. Do not build yet: Do not start collection and archiving until these checks pass. ### Phase 3 · Collection and archiving Build: Collection and archiving for Matomo Cloud: Install the generated tracker on the owned site and configure privacy/retention settings intentionally. - Install the generated tracker on the owned site and configure privacy/retention settings intentionally. - Run the upstream console archive task, schedule it with the documented URL and inspect its exit status and log age. - Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The campaign visit and configured goal appear after a successful archive run. Then check: Breaking database access makes archiving fail visibly instead of updating a false success timestamp. Record commands, observed results and the date in OPERATIONS.md. - Trap: A collecting tracker can coexist with stale reports when the archive job is broken. Done when: The campaign visit and configured goal appear after a successful archive run. Breaking database access makes archiving fail visibly instead of updating a false success timestamp. Do not build yet: Do not start complete backup and restore until these checks pass. ### Phase 4 · Complete backup and restore Build: Complete backup and restore for Matomo Cloud: Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. - Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. - Restore to an isolated installation with outbound tracking disabled and verify the site, goal and reports before planning an update. - Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The restored instance contains the fixture goal and site settings. Then check: Restoring only the database is documented as incomplete because configuration and custom files also matter. Record commands, observed results and the date in OPERATIONS.md. - Trap: Premium plugins and vendor-operated infrastructure are separate from the self-hosted core. Done when: The restored instance contains the fixture goal and site settings. Restoring only the database is documented as incomplete because configuration and custom files also matter. Do not build yet: Do not start portable delivery and clean-start proof until these checks pass. ### Phase 5 · Portable delivery and clean-start proof Build: Finish the Matomo Cloud replacement with a documented first-run path and a recoverable export. - Document prerequisites, every configuration variable, data locations and the three domain workflows: Install existing analytics; Collection and archiving; Complete backup and restore. Include the exclusions, actual costs and source check date 2026-09-05. Commands shown earlier that reference project files are files the builder must implement before running them. - Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. Restore into a separate empty directory or isolated deployment, with all outbound actions and schedules disabled. Recreate this proof: One owned site with a pageview, a campaign-tagged visit and a goal completion. Compare ids/counts and open the result before recording the restore date. Never test a restore over the only live copy. - Use a new folder and only README instructions to reach the fixture outcome. Verify upstream login, persistence, proof output and restore. Record exactly what passed; do not mark unrun checks complete. Commands, after creating the named files: `docker compose ps`. - Trap: Export without an import or restore rehearsal is not verified portability. Done when: A new folder reaches the documented fixture outcome using only README instructions. A backup restored in isolation preserves the proof data and can be opened. Do not build yet: Do not start operate and share with access controls until these checks pass. ### Phase 6 · Operate and share with access controls (product-builder only) Build: Product-builder only: make a self-hosted Matomo installation with working archives and recoverable data operable for its stated audience before allowing remote access. - Use upstream authentication, replace default credentials, restrict the editor/admin surface and inventory public ingestion/webhook paths. Review upstream edition and license boundaries before offering this as a service. - Put Caddy HTTPS in front of the upstream app, keep database and management ports private and configure public URLs from the chosen domain. For n8n, rehearse upstream PostgreSQL migration/import and recovery before claiming production readiness; disable any unused AI sandbox services. - Add a scheduled encrypted off-host backup using this procedure: Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. Monitor health, disk space, failed jobs and backup age. Stop the service to test an alert; rehearse recovery with outbound effects disabled and record recovery time. Rotate any exposed credentials and require reconciliation before resuming queues. - Trap: Product mode is additional engineering, not a switch that makes a local prototype production-ready. Done when: An unauthenticated visitor cannot read private records, download private files or mutate the admin surface. A viewer cannot mutate data by making a direct request, and guessed ids cannot cross ownership boundaries. Stopping the service triggers the configured alert and the latest off-host backup restores the fixture in isolation. Do not build yet: Do not add new providers or vendor-scale features until the release gates are recorded. ### Out of scope (and why) - This is a self-hosted Matomo installation with working archives and recoverable data; full Matomo Cloud feature parity, vendor hosting and support are not included. - mature analytics depth, privacy controls, hosted operations, and premium plugins: retain the paid product if this capability is essential; it is outside this bounded build. - identity stitching: retain the paid product if this capability is essential; it is outside this bounded build. - session replay: retain the paid product if this capability is essential; it is outside this bounded build. - warehouse connectors: retain the paid product if this capability is essential; it is outside this bounded build. - high-volume global ingestion and support: retain the paid product if this capability is essential; it is outside this bounded build. ### README must contain - Exact install, configure, initialize, start, test and recovery commands for a clean folder. - The schema, fixture, acceptance results, private data locations and export format. - Every prerequisite and secret source, actual running costs and deliberately excluded capabilities. - An honest distinction between tests actually run and checks still awaiting real credentials or deployment. - Dependency documentation reviewed 2026-09-05: https://matomo.org/faq/on-premise/installing-matomo/ ; https://matomo.org/faq/on-premise/what-are-the-requirements-and-recommendations-for-matomo-backup/. Recheck before upgrading; freeze the versions actually tested.
# Agent instructions · Matomo Cloud indie build - Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: Upstream Matomo container, Upstream-compatible MySQL/MariaDB, Docker Compose; Caddy for product HTTPS. Do not substitute. - Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes. - Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name. - Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced. - Do not invent cryptography, security guarantees, APIs or compliance claims. - Add a focused test for every destructive, security-sensitive or data-loss path the plan names. - Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs". ## Known traps - A valid Compose file proves configuration syntax only, not application health. - The task is operating Matomo, not cloning its tracking pipeline. - A collecting tracker can coexist with stale reports when the archive job is broken. - Premium plugins and vendor-operated infrastructure are separate from the self-hosted core. - Export without an import or restore rehearsal is not verified portability.
# Build plan · Matomo Cloud Build a self-hosted Matomo installation with working archives and recoverable data. Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note. ## Phase 1 · Deployment inventory and safe pilot Prepare the pinned upstream deployment for a self-hosted Matomo installation with working archives and recoverable data. ### Steps 1. Create the deployment files Read the linked upstream installation guide and create compose.yaml, .env.example, versions.txt and OPERATIONS.md. Map APP_IMAGE and only each service's required environment variables explicitly. Keep database ports internal and map the pilot application port to 127.0.0.1. Files: `compose.yaml`, `.env.example`, `versions.txt` 2. Identify every persistent asset Use the upstream Matomo MySQL/MariaDB schema. Back up its database, config/config.ini.php, custom plugin/theme files and the pinned application version together. Keep test site ids and archive-run evidence in OPERATIONS.md. Name each volume and its mount path in OPERATIONS.md; never use ephemeral container storage for the only copy. Create .env manually from .env.example and replace placeholders before starting. Files: `OPERATIONS.md`, `.gitignore` ```sh docker compose config --quiet ``` 3. Prepare the proof and recovery folder Create a private fixtures/ folder containing: One owned site with a pageview, a campaign-tagged visit and a goal completion. Create a separate backup destination and an isolated restore-project name; do not reuse live volumes in restore exercises. Files: `fixtures/README.md`, `OPERATIONS.md` ### Done when - [ ] docker compose config --quiet succeeds with no unresolved required variables. - [ ] The documented volume list includes every persistent asset and no secret is committed. ### Watch out - A valid Compose file proves configuration syntax only, not application health. ## Phase 2 · Install existing analytics Install existing analytics for Matomo Cloud: Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. ### Steps 1. Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. Files: `compose.yaml`, `OPERATIONS.md` 2. Complete the installer, create the admin and test site and record system-check results before adding tracking. Complete the installer, create the admin and test site and record system-check results before adding tracking. Files: `OPERATIONS.md` 3. Exercise the acceptance fixture Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The installer system checks pass and the dashboard opens with the new admin. Then check: A container restart preserves the site configuration and account. Record commands, observed results and the date in OPERATIONS.md. Files: `OPERATIONS.md` ### Done when - [ ] The installer system checks pass and the dashboard opens with the new admin. - [ ] A container restart preserves the site configuration and account. ### Watch out - The task is operating Matomo, not cloning its tracking pipeline. ## Phase 3 · Collection and archiving Collection and archiving for Matomo Cloud: Install the generated tracker on the owned site and configure privacy/retention settings intentionally. ### Steps 1. Install the generated tracker on the owned site and configure privacy/retention settings intentionally. Install the generated tracker on the owned site and configure privacy/retention settings intentionally. Files: `compose.yaml`, `OPERATIONS.md` 2. Run the upstream console archive task, schedule it with the documented URL and inspect its exit status and log age. Run the upstream console archive task, schedule it with the documented URL and inspect its exit status and log age. Files: `OPERATIONS.md` 3. Exercise the acceptance fixture Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The campaign visit and configured goal appear after a successful archive run. Then check: Breaking database access makes archiving fail visibly instead of updating a false success timestamp. Record commands, observed results and the date in OPERATIONS.md. Files: `OPERATIONS.md` ### Done when - [ ] The campaign visit and configured goal appear after a successful archive run. - [ ] Breaking database access makes archiving fail visibly instead of updating a false success timestamp. ### Watch out - A collecting tracker can coexist with stale reports when the archive job is broken. ## Phase 4 · Complete backup and restore Complete backup and restore for Matomo Cloud: Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. ### Steps 1. Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. Files: `compose.yaml`, `OPERATIONS.md` 2. Restore to an isolated installation with outbound tracking disabled and verify the site, goal and reports before planning an update. Restore to an isolated installation with outbound tracking disabled and verify the site, goal and reports before planning an update. Files: `OPERATIONS.md` 3. Exercise the acceptance fixture Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The restored instance contains the fixture goal and site settings. Then check: Restoring only the database is documented as incomplete because configuration and custom files also matter. Record commands, observed results and the date in OPERATIONS.md. Files: `OPERATIONS.md` ### Done when - [ ] The restored instance contains the fixture goal and site settings. - [ ] Restoring only the database is documented as incomplete because configuration and custom files also matter. ### Watch out - Premium plugins and vendor-operated infrastructure are separate from the self-hosted core. ## Phase 5 · Portable delivery and clean-start proof Finish the Matomo Cloud replacement with a documented first-run path and a recoverable export. ### Steps 1. Write the user-facing runbook Document prerequisites, every configuration variable, data locations and the three domain workflows: Install existing analytics; Collection and archiving; Complete backup and restore. Include the exclusions, actual costs and source check date 2026-09-05. Commands shown earlier that reference project files are files the builder must implement before running them. Files: `README.md`, `.env.example` 2. Create and rehearse a recoverable backup Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. Restore into a separate empty directory or isolated deployment, with all outbound actions and schedules disabled. Recreate this proof: One owned site with a pageview, a campaign-tagged visit and a goal completion. Compare ids/counts and open the result before recording the restore date. Never test a restore over the only live copy. Files: `OPERATIONS.md`, `backup/README.md` 3. Reproduce the first-run experience Use a new folder and only README instructions to reach the fixture outcome. Verify upstream login, persistence, proof output and restore. Record exactly what passed; do not mark unrun checks complete. Files: `README.md`, `verification.md` ```sh docker compose ps ``` ### Done when - [ ] A new folder reaches the documented fixture outcome using only README instructions. - [ ] A backup restored in isolation preserves the proof data and can be opened. ### Watch out - Export without an import or restore rehearsal is not verified portability. ## Not in this build - This is a self-hosted Matomo installation with working archives and recoverable data; full Matomo Cloud feature parity, vendor hosting and support are not included. - mature analytics depth, privacy controls, hosted operations, and premium plugins - identity stitching - session replay - warehouse connectors - high-volume global ingestion and support ## After v1, if you want it - Extend complete backup and restore only after the fixture and recovery checks pass. - Before adding another integration, document its credentials, limits, cost and failure behavior with primary-source links.
# Copy to .env and fill in. Never commit .env; this file documents it. # Required. Copy the exact application image reference selected from upstream into compose.yaml via this variable. APP_IMAGE=replace-with-tested-image-and-digest # Required. The loopback URL selected in compose.yaml; replace with your HTTPS origin only after completing product deployment. SITE_URL=http://localhost:8080 # Required · secret. Generate a dedicated database password and use it in the database service and Matomo installer; protect config/config.ini.php. DB_PASSWORD=replace-with-random-db-password
# Matomo Cloud · product brief ## Problem The core loop is buildable, but a dependable replacement becomes a real weekend or multi-day project. For Matomo Cloud, run first-party web analytics with goals, campaigns, and user-owned data. The hard boundary is mature analytics depth, privacy controls, hosted operations, and premium plugins, plus data pipeline reliability and analytical depth. ## Product outcome An operated version of a self-hosted Matomo installation with working archives and recoverable data, with authorized access, restore evidence and honest scope limits. ## Target user A builder who needs a maintainable product foundation, not a one-off demo. ## Required capabilities - Docker - ClickHouse - PostgreSQL - public HTTPS collector endpoint - site script access ## Explicit non-goals for v1 - This is a self-hosted Matomo installation with working archives and recoverable data; full Matomo Cloud feature parity, vendor hosting and support are not included. - mature analytics depth, privacy controls, hosted operations, and premium plugins - identity stitching - session replay - warehouse connectors - high-volume global ingestion and support ## Success criteria - The installer system checks pass and the dashboard opens with the new admin. - The campaign visit and configured goal appear after a successful archive run. - The restored instance contains the fixture goal and site settings. - A private-data authorization check passes using a second identity. - An off-host restore drill has a date, observed result and recovery time in OPERATIONS.md. - README names the excluded vendor capabilities and actual provider/hosting costs.
# Build brief · Matomo Cloud The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a self-hosted Matomo installation with working archives and recoverable data as a bounded replacement for Matomo Cloud. Build it in phases in the order below. Do not write the whole product in one pass. Finish the current phase, run its Done when checks, fix failures, then continue. Indie mode completes Phases 1-5. Phase 6 is required before shared or public deployment. ### Stack (fixed, do not substitute) - Application: Upstream Matomo container. Reuse the maintained application; the work is deployment and operations. - Storage: Upstream-compatible MySQL/MariaDB. Use the upstream schema and keep data across container replacement. - Deployment: Docker Compose; Caddy for product HTTPS. Explicit volumes, ports and configuration can be reviewed and recreated. ### Data model (create this before Phase 1) - Use the upstream Matomo MySQL/MariaDB schema. Back up its database, config/config.ini.php, custom plugin/theme files and the pinned application version together. Keep test site ids and archive-run evidence in OPERATIONS.md. - Use stable ids and explicit relationships; add auxiliary tables named by the phases before those phases use them. - Acceptance fixture: One owned site with a pageview, a campaign-tagged visit and a goal completion. ### Prerequisites and configuration - Docker Engine and Compose v2: Install Docker Engine and the Compose plugin on Linux using the official instructions. On Windows use Docker Desktop with WSL2, then work inside a Linux project folder. Verify: docker compose version prints a v2 version and docker info reaches the daemon. Cost: Docker Engine has no hosting fee; Desktop licensing depends on your use, and a rented host is billed separately. - Choose and record the upstream release: Open https://matomo.org/faq/on-premise/installing-matomo/, choose a stable release compatible with its database requirements, record its tag and resolved digest in versions.txt, and use those values in compose.yaml. Avoid unattended latest-tag updates. Verify: versions.txt names both application and database versions or states that the pilot uses embedded SQLite. Cost: Software/edition terms and optional paid features are defined by the upstream project. - Matomo Cloud acceptance sample: Create synthetic sample data before implementation: One owned site with a pageview, a campaign-tagged visit and a goal completion. Save it under fixtures/ with the expected results in fixtures/README.md; use no real credentials or customer records. Verify: The fixture files and expected outcomes exist and can be inspected without a vendor account. Cost: No paid service required for this local step. - Confirm the bounded replacement: The deliverable is a self-hosted Matomo installation with working archives and recoverable data. Read every exclusion below. Indie mode runs locally; any public or shared use requires the product access and deployment gates first. Verify: You can name the primary workflow and the vendor features this version deliberately leaves out. Cost: No paid service required for this local step. - Configuration: APP_IMAGE, SITE_URL, DB_PASSWORD. Ship .env.example, replace placeholders and exclude secrets from git. ### Phase 1 · Deployment inventory and safe pilot Build: Prepare the pinned upstream deployment for a self-hosted Matomo installation with working archives and recoverable data. - Read the linked upstream installation guide and create compose.yaml, .env.example, versions.txt and OPERATIONS.md. Map APP_IMAGE and only each service's required environment variables explicitly. Keep database ports internal and map the pilot application port to 127.0.0.1. - Use the upstream Matomo MySQL/MariaDB schema. Back up its database, config/config.ini.php, custom plugin/theme files and the pinned application version together. Keep test site ids and archive-run evidence in OPERATIONS.md. Name each volume and its mount path in OPERATIONS.md; never use ephemeral container storage for the only copy. Create .env manually from .env.example and replace placeholders before starting. Commands, after creating the named files: `docker compose config --quiet`. - Create a private fixtures/ folder containing: One owned site with a pageview, a campaign-tagged visit and a goal completion. Create a separate backup destination and an isolated restore-project name; do not reuse live volumes in restore exercises. - Trap: A valid Compose file proves configuration syntax only, not application health. Done when: docker compose config --quiet succeeds with no unresolved required variables. The documented volume list includes every persistent asset and no secret is committed. Do not build yet: Do not start install existing analytics until these checks pass. ### Phase 2 · Install existing analytics Build: Install existing analytics for Matomo Cloud: Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. - Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. - Complete the installer, create the admin and test site and record system-check results before adding tracking. - Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The installer system checks pass and the dashboard opens with the new admin. Then check: A container restart preserves the site configuration and account. Record commands, observed results and the date in OPERATIONS.md. - Trap: The task is operating Matomo, not cloning its tracking pipeline. Done when: The installer system checks pass and the dashboard opens with the new admin. A container restart preserves the site configuration and account. Do not build yet: Do not start collection and archiving until these checks pass. ### Phase 3 · Collection and archiving Build: Collection and archiving for Matomo Cloud: Install the generated tracker on the owned site and configure privacy/retention settings intentionally. - Install the generated tracker on the owned site and configure privacy/retention settings intentionally. - Run the upstream console archive task, schedule it with the documented URL and inspect its exit status and log age. - Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The campaign visit and configured goal appear after a successful archive run. Then check: Breaking database access makes archiving fail visibly instead of updating a false success timestamp. Record commands, observed results and the date in OPERATIONS.md. - Trap: A collecting tracker can coexist with stale reports when the archive job is broken. Done when: The campaign visit and configured goal appear after a successful archive run. Breaking database access makes archiving fail visibly instead of updating a false success timestamp. Do not build yet: Do not start complete backup and restore until these checks pass. ### Phase 4 · Complete backup and restore Build: Complete backup and restore for Matomo Cloud: Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. - Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. - Restore to an isolated installation with outbound tracking disabled and verify the site, goal and reports before planning an update. - Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The restored instance contains the fixture goal and site settings. Then check: Restoring only the database is documented as incomplete because configuration and custom files also matter. Record commands, observed results and the date in OPERATIONS.md. - Trap: Premium plugins and vendor-operated infrastructure are separate from the self-hosted core. Done when: The restored instance contains the fixture goal and site settings. Restoring only the database is documented as incomplete because configuration and custom files also matter. Do not build yet: Do not start portable delivery and clean-start proof until these checks pass. ### Phase 5 · Portable delivery and clean-start proof Build: Finish the Matomo Cloud replacement with a documented first-run path and a recoverable export. - Document prerequisites, every configuration variable, data locations and the three domain workflows: Install existing analytics; Collection and archiving; Complete backup and restore. Include the exclusions, actual costs and source check date 2026-09-05. Commands shown earlier that reference project files are files the builder must implement before running them. - Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. Restore into a separate empty directory or isolated deployment, with all outbound actions and schedules disabled. Recreate this proof: One owned site with a pageview, a campaign-tagged visit and a goal completion. Compare ids/counts and open the result before recording the restore date. Never test a restore over the only live copy. - Use a new folder and only README instructions to reach the fixture outcome. Verify upstream login, persistence, proof output and restore. Record exactly what passed; do not mark unrun checks complete. Commands, after creating the named files: `docker compose ps`. - Trap: Export without an import or restore rehearsal is not verified portability. Done when: A new folder reaches the documented fixture outcome using only README instructions. A backup restored in isolation preserves the proof data and can be opened. Do not build yet: Do not start operate and share with access controls until these checks pass. ### Phase 6 · Operate and share with access controls (product-builder only) Build: Product-builder only: make a self-hosted Matomo installation with working archives and recoverable data operable for its stated audience before allowing remote access. - Use upstream authentication, replace default credentials, restrict the editor/admin surface and inventory public ingestion/webhook paths. Review upstream edition and license boundaries before offering this as a service. - Put Caddy HTTPS in front of the upstream app, keep database and management ports private and configure public URLs from the chosen domain. For n8n, rehearse upstream PostgreSQL migration/import and recovery before claiming production readiness; disable any unused AI sandbox services. - Add a scheduled encrypted off-host backup using this procedure: Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. Monitor health, disk space, failed jobs and backup age. Stop the service to test an alert; rehearse recovery with outbound effects disabled and record recovery time. Rotate any exposed credentials and require reconciliation before resuming queues. - Trap: Product mode is additional engineering, not a switch that makes a local prototype production-ready. Done when: An unauthenticated visitor cannot read private records, download private files or mutate the admin surface. A viewer cannot mutate data by making a direct request, and guessed ids cannot cross ownership boundaries. Stopping the service triggers the configured alert and the latest off-host backup restores the fixture in isolation. Do not build yet: Do not add new providers or vendor-scale features until the release gates are recorded. ### Out of scope (and why) - This is a self-hosted Matomo installation with working archives and recoverable data; full Matomo Cloud feature parity, vendor hosting and support are not included. - mature analytics depth, privacy controls, hosted operations, and premium plugins: retain the paid product if this capability is essential; it is outside this bounded build. - identity stitching: retain the paid product if this capability is essential; it is outside this bounded build. - session replay: retain the paid product if this capability is essential; it is outside this bounded build. - warehouse connectors: retain the paid product if this capability is essential; it is outside this bounded build. - high-volume global ingestion and support: retain the paid product if this capability is essential; it is outside this bounded build. ### README must contain - Exact install, configure, initialize, start, test and recovery commands for a clean folder. - The schema, fixture, acceptance results, private data locations and export format. - Every prerequisite and secret source, actual running costs and deliberately excluded capabilities. - An honest distinction between tests actually run and checks still awaiting real credentials or deployment. - Dependency documentation reviewed 2026-09-05: https://matomo.org/faq/on-premise/installing-matomo/ ; https://matomo.org/faq/on-premise/what-are-the-requirements-and-recommendations-for-matomo-backup/. Recheck before upgrading; freeze the versions actually tested.
# Architecture · Matomo Cloud ## Stack | Part | Choice | Why | | --- | --- | --- | | Application | Upstream Matomo container | Reuse the maintained application; the work is deployment and operations. | | Storage | Upstream-compatible MySQL/MariaDB | Use the upstream schema and keep data across container replacement. | | Deployment | Docker Compose; Caddy for product HTTPS | Explicit volumes, ports and configuration can be reviewed and recreated. | ## Modules Each module has one owner concern and a documented way to replace it. | Module | Owns | How to replace it | | --- | --- | --- | | Data and identity | Use the upstream Matomo MySQL/MariaDB schema. Back up its database, config/config.ini.php, custom plugin/theme files and the pinned application version together. Keep test site ids and archive-run evidence in OPERATIONS.md. | Follow upstream migration procedures and verify a restored fixture before switching stores. | | Install existing analytics | Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. | Keep the acceptance contract: The installer system checks pass and the dashboard opens with the new admin. Replace only this module after replaying its fixture; preserve ids and existing records. | | Collection and archiving | Install the generated tracker on the owned site and configure privacy/retention settings intentionally. | Keep the acceptance contract: The campaign visit and configured goal appear after a successful archive run. Replace only this module after replaying its fixture; preserve ids and existing records. | | Complete backup and restore | Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. | Keep the acceptance contract: The restored instance contains the fixture goal and site settings. Replace only this module after replaying its fixture; preserve ids and existing records. | | Operations | Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. | Change host or backup destination only after an isolated restore and authorization check. | ## Configuration Every runtime setting is an environment variable documented in `.env.example`, validated at startup, with a safe local default wherever one exists. - `APP_IMAGE` · required · Copy the exact application image reference selected from upstream into compose.yaml via this variable. - `SITE_URL` · required · The loopback URL selected in compose.yaml; replace with your HTTPS origin only after completing product deployment. - `DB_PASSWORD` · required, secret · Generate a dedicated database password and use it in the database service and Matomo installer; protect config/config.ini.php. ## Production baseline - Security: least privilege, input validation at every boundary, secret redaction in logs, rate limits on abuse-prone paths, no invented security primitives. - Data: explicit schema and migrations, transactional writes where integrity matters, backup and restore procedures that have been exercised. - Integrations: adapters around third-party providers, idempotent webhook or job processing, bounded retries, timeouts. - Observability: structured logs with request or operation ids, an error-tracking hook, and health and readiness checks where a server exists. - Quality: unit tests for domain rules, integration tests at module boundaries, one end-to-end test of the critical path. ## Decision records For each dependency in the stack table, keep a short note: why it was chosen, its failure mode, and how it is replaced. Do not add infrastructure until a requirement in `PRODUCT.md` justifies it.
# Agent instructions · Matomo Cloud product build - Read `PRODUCT.md` and `ARCHITECTURE.md` before changing code. The stack is fixed: Upstream Matomo container, Upstream-compatible MySQL/MariaDB, Docker Compose; Caddy for product HTTPS. - Implement milestone by milestone from `MILESTONES.md`; keep each change reviewable and leave the application runnable at every commit. - Treat authentication, payments, encryption, imports, webhooks and destructive actions as high-risk boundaries when present. - Never invent cryptography or silently weaken a requirement to make a check pass. - Put every external service behind an interface with a deterministic fake for tests. - Add migrations and rollback or recovery notes for every persistent data change. - Log useful operational context without credentials, tokens, passwords or personal data. - Update documentation and run every check before completing a milestone. ## Known traps - A valid Compose file proves configuration syntax only, not application health. - The task is operating Matomo, not cloning its tracking pipeline. - A collecting tracker can coexist with stale reports when the archive job is broken. - Premium plugins and vendor-operated infrastructure are separate from the self-hosted core. - Export without an import or restore rehearsal is not verified portability. - Product mode is additional engineering, not a switch that makes a local prototype production-ready.
# Delivery milestones · Matomo Cloud Estimated effort: **multi-day** for the indie phases; the production-only milestones add the trust and operability layer. ## M1 · Deployment inventory and safe pilot Prepare the pinned upstream deployment for a self-hosted Matomo installation with working archives and recoverable data. ### Steps 1. Create the deployment files Read the linked upstream installation guide and create compose.yaml, .env.example, versions.txt and OPERATIONS.md. Map APP_IMAGE and only each service's required environment variables explicitly. Keep database ports internal and map the pilot application port to 127.0.0.1. Files: `compose.yaml`, `.env.example`, `versions.txt` 2. Identify every persistent asset Use the upstream Matomo MySQL/MariaDB schema. Back up its database, config/config.ini.php, custom plugin/theme files and the pinned application version together. Keep test site ids and archive-run evidence in OPERATIONS.md. Name each volume and its mount path in OPERATIONS.md; never use ephemeral container storage for the only copy. Create .env manually from .env.example and replace placeholders before starting. Files: `OPERATIONS.md`, `.gitignore` ```sh docker compose config --quiet ``` 3. Prepare the proof and recovery folder Create a private fixtures/ folder containing: One owned site with a pageview, a campaign-tagged visit and a goal completion. Create a separate backup destination and an isolated restore-project name; do not reuse live volumes in restore exercises. Files: `fixtures/README.md`, `OPERATIONS.md` ### Done when - [ ] docker compose config --quiet succeeds with no unresolved required variables. - [ ] The documented volume list includes every persistent asset and no secret is committed. ### Watch out - A valid Compose file proves configuration syntax only, not application health. ## M2 · Install existing analytics Install existing analytics for Matomo Cloud: Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. ### Steps 1. Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. Deploy the official Matomo PHP application and a compatible database from the upstream install requirements; bind the app to loopback initially. Files: `compose.yaml`, `OPERATIONS.md` 2. Complete the installer, create the admin and test site and record system-check results before adding tracking. Complete the installer, create the admin and test site and record system-check results before adding tracking. Files: `OPERATIONS.md` 3. Exercise the acceptance fixture Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The installer system checks pass and the dashboard opens with the new admin. Then check: A container restart preserves the site configuration and account. Record commands, observed results and the date in OPERATIONS.md. Files: `OPERATIONS.md` ### Done when - [ ] The installer system checks pass and the dashboard opens with the new admin. - [ ] A container restart preserves the site configuration and account. ### Watch out - The task is operating Matomo, not cloning its tracking pipeline. ## M3 · Collection and archiving Collection and archiving for Matomo Cloud: Install the generated tracker on the owned site and configure privacy/retention settings intentionally. ### Steps 1. Install the generated tracker on the owned site and configure privacy/retention settings intentionally. Install the generated tracker on the owned site and configure privacy/retention settings intentionally. Files: `compose.yaml`, `OPERATIONS.md` 2. Run the upstream console archive task, schedule it with the documented URL and inspect its exit status and log age. Run the upstream console archive task, schedule it with the documented URL and inspect its exit status and log age. Files: `OPERATIONS.md` 3. Exercise the acceptance fixture Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The campaign visit and configured goal appear after a successful archive run. Then check: Breaking database access makes archiving fail visibly instead of updating a false success timestamp. Record commands, observed results and the date in OPERATIONS.md. Files: `OPERATIONS.md` ### Done when - [ ] The campaign visit and configured goal appear after a successful archive run. - [ ] Breaking database access makes archiving fail visibly instead of updating a false success timestamp. ### Watch out - A collecting tracker can coexist with stale reports when the archive job is broken. ## M4 · Complete backup and restore Complete backup and restore for Matomo Cloud: Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. ### Steps 1. Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. Back up the database plus config and custom files as one dated set; encrypt it off-host and keep a manifest. Files: `compose.yaml`, `OPERATIONS.md` 2. Restore to an isolated installation with outbound tracking disabled and verify the site, goal and reports before planning an update. Restore to an isolated installation with outbound tracking disabled and verify the site, goal and reports before planning an update. Files: `OPERATIONS.md` 3. Exercise the acceptance fixture Use One owned site with a pageview, a campaign-tagged visit and a goal completion. Check: The restored instance contains the fixture goal and site settings. Then check: Restoring only the database is documented as incomplete because configuration and custom files also matter. Record commands, observed results and the date in OPERATIONS.md. Files: `OPERATIONS.md` ### Done when - [ ] The restored instance contains the fixture goal and site settings. - [ ] Restoring only the database is documented as incomplete because configuration and custom files also matter. ### Watch out - Premium plugins and vendor-operated infrastructure are separate from the self-hosted core. ## M5 · Portable delivery and clean-start proof Finish the Matomo Cloud replacement with a documented first-run path and a recoverable export. ### Steps 1. Write the user-facing runbook Document prerequisites, every configuration variable, data locations and the three domain workflows: Install existing analytics; Collection and archiving; Complete backup and restore. Include the exclusions, actual costs and source check date 2026-09-05. Commands shown earlier that reference project files are files the builder must implement before running them. Files: `README.md`, `.env.example` 2. Create and rehearse a recoverable backup Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. Restore into a separate empty directory or isolated deployment, with all outbound actions and schedules disabled. Recreate this proof: One owned site with a pageview, a campaign-tagged visit and a goal completion. Compare ids/counts and open the result before recording the restore date. Never test a restore over the only live copy. Files: `OPERATIONS.md`, `backup/README.md` 3. Reproduce the first-run experience Use a new folder and only README instructions to reach the fixture outcome. Verify upstream login, persistence, proof output and restore. Record exactly what passed; do not mark unrun checks complete. Files: `README.md`, `verification.md` ```sh docker compose ps ``` ### Done when - [ ] A new folder reaches the documented fixture outcome using only README instructions. - [ ] A backup restored in isolation preserves the proof data and can be opened. ### Watch out - Export without an import or restore rehearsal is not verified portability. ## M6 · Operate and share with access controls (production only) Product-builder only: make a self-hosted Matomo installation with working archives and recoverable data operable for its stated audience before allowing remote access. ### Steps 1. Establish owner access before exposure Use upstream authentication, replace default credentials, restrict the editor/admin surface and inventory public ingestion/webhook paths. Review upstream edition and license boundaries before offering this as a service. Files: `ARCHITECTURE.md`, `OPERATIONS.md` 2. Deploy a monitored service Put Caddy HTTPS in front of the upstream app, keep database and management ports private and configure public URLs from the chosen domain. For n8n, rehearse upstream PostgreSQL migration/import and recovery before claiming production readiness; disable any unused AI sandbox services. Files: `Caddyfile`, `OPERATIONS.md` 3. Rehearse loss and recovery Add a scheduled encrypted off-host backup using this procedure: Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. Monitor health, disk space, failed jobs and backup age. Stop the service to test an alert; rehearse recovery with outbound effects disabled and record recovery time. Rotate any exposed credentials and require reconciliation before resuming queues. Files: `OPERATIONS.md`, `release-checklist.md` ### Done when - [ ] An unauthenticated visitor cannot read private records, download private files or mutate the admin surface. - [ ] A viewer cannot mutate data by making a direct request, and guessed ids cannot cross ownership boundaries. - [ ] Stopping the service triggers the configured alert and the latest off-host backup restores the fixture in isolation. ### Watch out - Product mode is additional engineering, not a switch that makes a local prototype production-ready.
# Operations · Matomo Cloud ## Backup Create a consistent database dump plus config/config.ini.php, the pinned Matomo version and custom files. ## Restore Restore into a separate empty directory or isolated deployment, with all outbound actions and schedules disabled. Recreate this proof: One owned site with a pageview, a campaign-tagged visit and a goal completion. Compare ids/counts and open the result before recording the restore date. Never test a restore over the only live copy. Do a restore drill before the first real user, and write the date here when it passes. ## Monitoring Check HTTP availability, free disk, backup age and domain failures for Install existing analytics, Collection and archiving, Complete backup and restore. Alert without logging private payloads. ## Incident checklist Pause outbound jobs and public intake as appropriate, preserve redacted diagnostics, restore an isolated verified backup, rotate affected credentials and reconcile uncertain effects before reopening. 1. Contain the issue without destroying evidence or user data. 2. Record the timeline and affected scope. 3. Rotate exposed secrets and revoke compromised sessions or credentials. 4. Restore from a verified backup when needed. 5. Document the root cause, the remediation and the regression test. ## Release gate - [ ] The installer system checks pass and the dashboard opens with the new admin. - [ ] The campaign visit and configured goal appear after a successful archive run. - [ ] The restored instance contains the fixture goal and site settings. - [ ] A private-data authorization check passes using a second identity. - [ ] An off-host restore drill has a date, observed result and recovery time in OPERATIONS.md. - [ ] README names the excluded vendor capabilities and actual provider/hosting costs. ## Launch constraint Do not market omitted Matomo Cloud capabilities as implemented. The non-goals in `PRODUCT.md` remain user-visible limitations until they are deliberately delivered.
# Copy to .env and fill in. Never commit .env; this file documents it. # Required. Copy the exact application image reference selected from upstream into compose.yaml via this variable. APP_IMAGE=replace-with-tested-image-and-digest # Required. The loopback URL selected in compose.yaml; replace with your HTTPS origin only after completing product deployment. SITE_URL=http://localhost:8080 # Required · secret. Generate a dedicated database password and use it in the database service and Matomo installer; protect config/config.ini.php. DB_PASSWORD=replace-with-random-db-password
$ choose a build depth, inspect the files, then open the complete pack in your agent
People still pay for Matomo Cloud because teams pay because analytics must keep collecting and remain trustworthy while the product changes underneath it. The recurring cost buys event schemas, bot filtering, identity, late data, retention, query cost, privacy, backups, and always-on ingestion, not just the visible interface.
xmature analytics depth, privacy controls, hosted operations, and premium plugins
xidentity stitching
xsession replay
xwarehouse connectors
xhigh-volume global ingestion and support
Don't feel like building it? These folks already made it free.
no votes, no pay-to-list · just what's real
Matomo Cloud pricing
| plan | monthly | annual (per mo) | what you get |
|---|---|---|---|
| business, 50,000 hits | $26/workspace | $21.67/workspace | 50,000 hits/month, 30 websites, 30 team members, 100 segments, 150 goals, 30 custom dimensions, 24 months raw-data retention, and report retention forever |
| business, 100,000 hits | $42/workspace | $35/workspace | 100,000 hits/month, 30 websites, 30 team members, 100 segments, 150 goals, 30 custom dimensions, 24 months raw-data retention, and report retention forever |
| business, 300,000 hits | $85/workspace | $70.83/workspace | 300,000 hits/month, 30 websites, 30 team members, 100 segments, 150 goals, 30 custom dimensions, 24 months raw-data retention, and report retention forever |
| business, 600,000 hits | $139/workspace | $115.83/workspace | 600,000 hits/month, 30 websites, 30 team members, 100 segments, 150 goals, 30 custom dimensions, 24 months raw-data retention, and report retention forever |
| business, 1 million hits | $204/workspace | $170/workspace | 1,000,000 hits/month, 30 websites, 30 team members, 100 segments, 150 goals, 30 custom dimensions, 24 months raw-data retention, and report retention forever |
| business, 2 million hits | $399/workspace | $332.50/workspace | 2,000,000 hits/month, 30 websites, 30 team members, 100 segments, 150 goals, 30 custom dimensions, 24 months raw-data retention, and report retention forever |
| business, 5 million hits | $975/workspace | $812.50/workspace | 5,000,000 hits/month, 30 websites, 30 team members, 100 segments, 150 goals, 30 custom dimensions, 24 months raw-data retention, and report retention forever |
| enterprise | custom | — | Custom allowances; required above 10 million hits/month |
free tierno free tier
billingmonthly + annual (2 months free, about -17%); no-card free trial; plan changes are prorated
hidden costsHits above the allowance are billed as overages rather than blocked; the current page exposes $2.60 per extra 5,000 hits on the 50,000-hit plan, while other bracket overage rates are not published in the static table. Crash reports, events, and other tracking requests consume the same hit quota.
verified 2026-08-12 · source ↗
Vibecode Matomo Cloud
Kinda. The core of Matomo Cloud is buildable in a weekend with the prompt on this page, but there are real gaps: mature analytics depth, privacy controls, hosted operations, and premium plugins, identity stitching. Read the honest list above before committing.
How much does Matomo Cloud cost?
Matomo Cloud costs about $26/month (Essential, checked 2026-07-31), which is $312 per year.
What do I lose by replacing Matomo Cloud?
Honestly: mature analytics depth, privacy controls, hosted operations, and premium plugins; identity stitching; session replay; warehouse connectors; high-volume global ingestion and support. If any of those are load-bearing for you, keep paying.
Is there an open-source alternative to Matomo Cloud?
Yes: Umami (Goals, campaigns and first-party data in a much smaller self-hosted package.) Matomo (The same analytics engine with goals and campaigns; you replace the cloud bill with PHP and database upkeep.) The prompt is for when you want it exactly your way.