diff --git a/public/icons/charts/alfio.png b/public/icons/charts/alfio.png index 4123399a..3f82cf83 100644 Binary files a/public/icons/charts/alfio.png and b/public/icons/charts/alfio.png differ diff --git a/public/icons/charts/booklore.png b/public/icons/charts/booklore.png index e2561d96..32737bb0 100644 Binary files a/public/icons/charts/booklore.png and b/public/icons/charts/booklore.png differ diff --git a/public/icons/charts/clickhouse.png b/public/icons/charts/clickhouse.png new file mode 100644 index 00000000..4f709a24 Binary files /dev/null and b/public/icons/charts/clickhouse.png differ diff --git a/public/icons/charts/cronicle.png b/public/icons/charts/cronicle.png index 7d2a37a3..c643aef6 100644 Binary files a/public/icons/charts/cronicle.png and b/public/icons/charts/cronicle.png differ diff --git a/public/icons/charts/dolibarr.png b/public/icons/charts/dolibarr.png index 09858c14..6027800e 100644 Binary files a/public/icons/charts/dolibarr.png and b/public/icons/charts/dolibarr.png differ diff --git a/public/icons/charts/fastmcp-server.png b/public/icons/charts/fastmcp-server.png index c7710f75..faadf2cb 100644 Binary files a/public/icons/charts/fastmcp-server.png and b/public/icons/charts/fastmcp-server.png differ diff --git a/public/icons/charts/ghost.png b/public/icons/charts/ghost.png index ef55a1d9..d275888e 100644 Binary files a/public/icons/charts/ghost.png and b/public/icons/charts/ghost.png differ diff --git a/public/icons/charts/kafka.png b/public/icons/charts/kafka.png index 6af01d99..58ebdbb5 100644 Binary files a/public/icons/charts/kafka.png and b/public/icons/charts/kafka.png differ diff --git a/public/icons/charts/matomo.png b/public/icons/charts/matomo.png new file mode 100644 index 00000000..4158da4c Binary files /dev/null and b/public/icons/charts/matomo.png differ diff --git a/public/icons/charts/metabase.png b/public/icons/charts/metabase.png index 31feb86e..8d7a0dd5 100644 Binary files a/public/icons/charts/metabase.png and b/public/icons/charts/metabase.png differ diff --git a/public/icons/charts/ntfy.png b/public/icons/charts/ntfy.png index 05c6fd88..7809488e 100644 Binary files a/public/icons/charts/ntfy.png and b/public/icons/charts/ntfy.png differ diff --git a/public/icons/charts/strava-statistics.png b/public/icons/charts/strava-statistics.png index 29e9d413..e2c45d28 100644 Binary files a/public/icons/charts/strava-statistics.png and b/public/icons/charts/strava-statistics.png differ diff --git a/public/icons/charts/umami.png b/public/icons/charts/umami.png index 2ed390e8..84d71420 100644 Binary files a/public/icons/charts/umami.png and b/public/icons/charts/umami.png differ diff --git a/src/data/charts.ts b/src/data/charts.ts index 9b4682f2..9d9eb5f9 100644 --- a/src/data/charts.ts +++ b/src/data/charts.ts @@ -55,6 +55,14 @@ export const charts: Chart[] = [ maturity: 'stable', backup: true, }, + { + name: 'ClickHouse', + slug: 'clickhouse', + description: + 'Standalone ClickHouse OLAP database with official images, persistent storage, metrics, ESO, and safety guards.', + maturity: 'beta', + backup: false, + }, { name: 'RabbitMQ', slug: 'rabbitmq', @@ -105,6 +113,13 @@ export const charts: Chart[] = [ maturity: 'stable', backup: true, }, + { + name: 'Matomo', + slug: 'matomo', + description: 'Privacy-first analytics with official Matomo image, MySQL, archiver CronJob, Gateway API, and ESO.', + maturity: 'beta', + backup: false, + }, { name: 'Strapi', slug: 'strapi', diff --git a/src/data/navigation.ts b/src/data/navigation.ts index 2530b135..30d4707b 100644 --- a/src/data/navigation.ts +++ b/src/data/navigation.ts @@ -34,6 +34,7 @@ export const chartCategories: ChartCategory[] = [ { label: 'Valkey', href: '/docs/charts/valkey', maturity: 'stable' }, { label: 'Memcached', href: '/docs/charts/memcached', maturity: 'stable' }, { label: 'Qdrant', href: '/docs/charts/qdrant', maturity: 'stable' }, + { label: 'ClickHouse', href: '/docs/charts/clickhouse', maturity: 'beta' }, ], }, { @@ -160,6 +161,7 @@ export const chartCategories: ChartCategory[] = [ { label: 'Apache Druid', href: '/docs/charts/druid', maturity: 'stable' }, { label: 'Kibana', href: '/docs/charts/kibana', maturity: 'stable' }, { label: 'Elasticsearch', href: '/docs/charts/elasticsearch', maturity: 'stable' }, + { label: 'Matomo', href: '/docs/charts/matomo', maturity: 'beta' }, ], }, { diff --git a/src/data/playground-configs.ts b/src/data/playground-configs.ts index 6b58afdd..60ccd210 100644 --- a/src/data/playground-configs.ts +++ b/src/data/playground-configs.ts @@ -8,6 +8,165 @@ // field definitions from values.schema.json. export const chartConfigs: Record = { + clickhouse: [ + { + name: 'Database', + fields: [ + { + label: 'Database', + key: 'clickhouse.database', + type: 'text', + default: 'default', + description: 'Initial database created on empty data dir', + }, + { + label: 'User', + key: 'clickhouse.user', + type: 'text', + default: 'default', + description: 'Initial ClickHouse user', + }, + { + label: 'Password', + key: 'clickhouse.password', + type: 'text', + default: '', + description: 'Initial password; use a Secret for production', + }, + ], + }, + { + name: 'Storage', + fields: [ + { + label: 'Data Size', + key: 'persistence.size', + type: 'text', + default: '20Gi', + description: 'Persistent volume size for /var/lib/clickhouse', + }, + { + label: 'Persist Logs', + key: 'logs.persistence.enabled', + type: 'toggle', + default: 'false', + description: 'Store /var/log/clickhouse-server on a separate PVC', + }, + ], + }, + { + name: 'Observability', + collapsible: true, + gateField: 'metrics.enabled', + fields: [ + { + label: 'ServiceMonitor', + key: 'metrics.serviceMonitor.enabled', + type: 'toggle', + default: 'false', + description: 'Create Prometheus Operator ServiceMonitor', + }, + ], + }, + { + name: 'Network Policy', + collapsible: true, + gateField: 'networkPolicy.enabled', + fields: [ + { + label: 'Egress Policy', + key: 'networkPolicy.egress.enabled', + type: 'toggle', + default: 'false', + description: 'Render explicit egress policy', + }, + { + label: 'Extra Egress CIDR', + key: 'networkPolicy.egress.extraEgress[0].to[0].ipBlock.cidr', + type: 'text', + default: '10.0.0.0/8', + description: 'Additional egress destination', + }, + ], + }, + ], + matomo: [ + { + name: 'Application', + fields: [ + { + label: 'Site URL', + key: 'matomo.siteUrl', + type: 'text', + default: 'https://analytics.example.com', + description: 'Public URL used by the archiver', + }, + { + label: 'Trusted Host', + key: 'matomo.trustedHost', + type: 'text', + default: 'analytics.example.com', + description: 'Expected external host behind ingress or Gateway API', + }, + ], + }, + { + name: 'Database', + collapsible: true, + fields: [ + { + label: 'Bundled MySQL', + key: 'mysql.enabled', + type: 'toggle', + default: 'true', + description: 'Disable to use external MySQL or MariaDB', + }, + { + label: 'External Host', + key: 'database.external.host', + type: 'text', + default: '', + description: 'External MySQL/MariaDB host', + }, + ], + }, + { + name: 'Archiver', + collapsible: true, + gateField: 'archiver.enabled', + fields: [ + { + label: 'Schedule', + key: 'archiver.schedule', + type: 'text', + default: '5 * * * *', + description: 'Cron schedule for core:archive', + }, + ], + }, + { + name: 'Ingress', + collapsible: true, + gateField: 'ingress.enabled', + fields: [ + { + label: 'Hostname', + key: 'ingress.hosts[0].host', + type: 'text', + default: 'analytics.example.com', + description: 'Ingress host', + }, + { + label: 'Ingress Class', + key: 'ingress.ingressClassName', + type: 'select', + default: 'nginx', + options: ['', 'nginx', 'traefik'], + description: 'Ingress controller class', + }, + ], + }, + ], generic: [ { name: 'Workload', diff --git a/src/pages/docs/charts/clickhouse.mdx b/src/pages/docs/charts/clickhouse.mdx new file mode 100644 index 00000000..085557b7 --- /dev/null +++ b/src/pages/docs/charts/clickhouse.mdx @@ -0,0 +1,243 @@ +--- +layout: ../../../layouts/DocsLayout.astro +title: ClickHouse Chart +description: ClickHouse Helm chart with official image, persistent standalone StatefulSet, metrics, External Secrets, NetworkPolicy, and explicit replication guardrails. +--- + +# ClickHouse + +ClickHouse is a fast column-oriented OLAP database. The HelmForge chart deploys the official ClickHouse server image as a production-safe standalone StatefulSet with persistent storage, metrics wiring, and explicit guardrails against unsafe Helm-only replication. + +## Key Features + +- Official `docker.io/clickhouse/clickhouse-server` image pinned to `25.8.28.1` +- StatefulSet with persistent `/var/lib/clickhouse` +- Client Service exposing HTTP `8123` and native TCP `9000` +- Headless Service for stable pod DNS +- Optional persistent `/var/log/clickhouse-server` +- Built-in Prometheus metrics endpoint and ServiceMonitor support +- External Secrets Operator support for the initial user password +- NetworkPolicy, dual-stack Service fields, PDB, and Helm tests +- Validation guard that blocks `replicaCount > 1` + + + +## Installation + +```bash +helm repo add helmforge https://repo.helmforge.dev +helm repo update +helm install clickhouse helmforge/clickhouse --namespace clickhouse --create-namespace +``` + +```bash +helm install clickhouse oci://ghcr.io/helmforgedev/helm/clickhouse --namespace clickhouse --create-namespace +``` + +## Examples + +Standalone: + +```yaml +persistence: + enabled: true + size: 50Gi +``` + +Production baseline: + +```yaml +clickhouse: + database: analytics + user: analytics + existingSecret: clickhouse-auth + existingSecretPasswordKey: clickhouse-password + +persistence: + enabled: true + size: 200Gi + +metrics: + enabled: true + serviceMonitor: + enabled: true + +networkPolicy: + enabled: true + egress: + enabled: true +``` + +## Architecture + +The chart intentionally targets standalone ClickHouse. It renders one StatefulSet, one client Service, and one headless Service. This keeps the Helm chart operationally clear and avoids pretending that replica count alone creates a safe distributed ClickHouse cluster. + +For sharded or replicated deployments, use ClickHouse Operator or Altinity operator workflows. Replication requires Keeper or ZooKeeper, cluster definitions, failure-domain planning, and cluster-aware operations that are outside this standalone chart. + +## Production Values + +```yaml +replicaCount: 1 + +clickhouse: + database: analytics + user: analytics + existingSecret: clickhouse-auth + existingSecretPasswordKey: clickhouse-password + defaultAccessManagement: true + +persistence: + enabled: true + size: 200Gi + +logs: + persistence: + enabled: true + size: 20Gi + +resources: + requests: + cpu: '2' + memory: 8Gi + limits: + memory: 16Gi + +metrics: + enabled: true + serviceMonitor: + enabled: true + +networkPolicy: + enabled: true + egress: + enabled: true +``` + +## Authentication + +The official image initializes the configured database and user on an empty data directory. Use an existing Secret or External Secrets Operator for production passwords: + +```yaml +clickhouse: + database: analytics + user: analytics + existingSecret: clickhouse-auth + existingSecretPasswordKey: clickhouse-password +``` + +Leaving `clickhouse.password` empty leaves the initial user passwordless. That is acceptable only for isolated local evaluation. + +## External Secrets + +```yaml +clickhouse: + existingSecret: clickhouse-auth + existingSecretPasswordKey: clickhouse-password + +externalSecrets: + enabled: true + items: + - name: clickhouse-auth + secretStoreRef: + name: cluster-secrets + kind: ClusterSecretStore + target: + name: clickhouse-auth + data: + - secretKey: clickhouse-password + remoteRef: + key: production/clickhouse + property: password +``` + +## Observability + +ClickHouse can expose its built-in Prometheus endpoint on port `9363`: + +```yaml +metrics: + enabled: true + path: /metrics + serviceMonitor: + enabled: true + interval: 30s + scrapeTimeout: 10s +``` + +The chart does not deploy a metrics sidecar. It enables the native server endpoint in the rendered ClickHouse configuration. + +## Networking + +The client Service exposes: + +| Port | Default | Purpose | +| ------------- | ------- | ----------------------------------------------- | +| `http` | `8123` | HTTP API and health checks. | +| `tcp` | `9000` | Native ClickHouse TCP protocol. | +| `interserver` | `9009` | Interserver HTTP port exposed for completeness. | +| `metrics` | `9363` | Prometheus metrics when enabled. | + +Ingress and Gateway API are intentionally not part of this chart because ClickHouse is a database service, not a web application. Expose it through private networking, controlled Services, or platform-specific TCP routing. + +Dual-stack Service fields are available when the cluster supports them: + +```yaml +service: + ipFamilyPolicy: PreferDualStack + ipFamilies: + - IPv4 + - IPv6 +``` + +## Validation + +After deployment: + +```bash +helm test clickhouse -n clickhouse +kubectl get pods -n clickhouse -l app.kubernetes.io/name=clickhouse +kubectl logs -n clickhouse statefulset/clickhouse --since=10m +kubectl exec -n clickhouse statefulset/clickhouse -- clickhouse-client --query "SELECT version()" +``` + +Also validate persistence across restart, metrics scraping, password authentication, and backup strategy before production use. + +## Common Issues + +| Symptom | Likely Cause | Fix | +| ------------------------------------------ | ------------------------------------------------------ | --------------------------------------------------------------------- | +| Helm render fails with replica count error | `replicaCount` is greater than `1` | Use `replicaCount=1` or move to ClickHouse Operator. | +| Password change does not apply | Existing data directory already initialized | Manage users with SQL after first initialization. | +| Metrics are missing | Native endpoint or ServiceMonitor disabled | Set `metrics.enabled=true` and `metrics.serviceMonitor.enabled=true`. | +| Pod cannot write data | Storage class permissions or security context mismatch | Check PVC binding and volume ownership for UID/GID `101`. | + + + +## Values + +| Parameter | Default | Description | +| -------------------------------------- | ---------------------------------------- | ---------------------------------------------------------- | +| `image.repository` | `docker.io/clickhouse/clickhouse-server` | Official ClickHouse image repository. | +| `image.tag` | `25.8.28.1` | Official full-version image tag. | +| `replicaCount` | `1` | ClickHouse pod count. Values greater than `1` are blocked. | +| `clickhouse.database` | `default` | Initial database on an empty data directory. | +| `clickhouse.user` | `default` | Initial user on an empty data directory. | +| `clickhouse.password` | `""` | Initial user password. | +| `clickhouse.existingSecret` | `""` | Existing Secret containing the initial password. | +| `clickhouse.existingSecretPasswordKey` | `clickhouse-password` | Key in the existing Secret containing the password. | +| `clickhouse.defaultAccessManagement` | `true` | Enables SQL-driven access management for the initial user. | +| `persistence.enabled` | `true` | Persist `/var/lib/clickhouse`. | +| `persistence.size` | `20Gi` | Data PVC size. | +| `logs.persistence.enabled` | `false` | Persist logs on a separate PVC. | +| `metrics.enabled` | `false` | Enable native Prometheus endpoint. | +| `metrics.serviceMonitor.enabled` | `false` | Render ServiceMonitor. | +| `externalSecrets.enabled` | `false` | Render ExternalSecret resources. | +| `networkPolicy.enabled` | `false` | Render NetworkPolicy. | +| `service.ipFamilyPolicy` | `""` | Kubernetes Service IP family policy. | +| `extraManifests` | `[]` | Additional Kubernetes manifests rendered with the release. | + +## Links + +- [ClickHouse](https://clickhouse.com/) +- [ClickHouse server image](https://hub.docker.com/r/clickhouse/clickhouse-server) +- [Chart source](https://github.com/helmforgedev/charts/tree/main/charts/clickhouse) diff --git a/src/pages/docs/charts/matomo.mdx b/src/pages/docs/charts/matomo.mdx new file mode 100644 index 00000000..89017bf4 --- /dev/null +++ b/src/pages/docs/charts/matomo.mdx @@ -0,0 +1,281 @@ +--- +layout: ../../../layouts/DocsLayout.astro +title: Matomo Chart +description: Matomo Helm chart with official image, HelmForge MySQL, external database support, archiver CronJob, Gateway API, and production controls. +--- + +# Matomo + +Matomo is a privacy-first web analytics platform. The HelmForge chart deploys the official Matomo Apache image with persistent application storage, MySQL integration, and a scheduled `core:archive` CronJob for production report processing. + +## Key Features + +- Official `docker.io/library/matomo` image pinned to `5.11.2-apache` +- HelmForge MySQL dependency for self-contained deployments +- External MySQL or MariaDB mode for production databases +- Persistent `/var/www/html` storage for application files and plugins +- CronJob-based Matomo report archiving +- Ingress, Gateway API HTTPRoute, dual-stack Service fields, NetworkPolicy, PDB, and Helm tests +- External Secrets Operator support for database credentials +- `extraManifests` extension point for companion resources + + + +## Installation + +```bash +helm repo add helmforge https://repo.helmforge.dev +helm repo update +helm install matomo helmforge/matomo --namespace matomo --create-namespace +``` + +```bash +helm install matomo oci://ghcr.io/helmforgedev/helm/matomo --namespace matomo --create-namespace +``` + +## Examples + +Bundled MySQL: + +```yaml +mysql: + enabled: true +matomo: + siteUrl: https://analytics.example.com +``` + +External database: + +```yaml +mysql: + enabled: false + +database: + mode: external + external: + host: mysql.database.svc.cluster.local + name: matomo + username: matomo + existingSecret: matomo-database + existingSecretPasswordKey: database-password + +matomo: + siteUrl: https://analytics.example.com + trustedHost: analytics.example.com +``` + +## Architecture + +The chart runs the Apache variant of the official Matomo container as a Deployment and stores Matomo application files on a PVC. Database connectivity is explicit: + +- `database.mode=auto` uses bundled MySQL when `mysql.enabled=true` +- `database.mode=mysql` forces the HelmForge MySQL subchart path +- `database.mode=external` uses an external MySQL or MariaDB endpoint + +For production, prefer a managed or platform-operated MySQL or MariaDB service and keep Matomo application files persistent. The bundled MySQL path is useful for self-contained environments and local validation. + +## Production Values + +```yaml +mysql: + enabled: false + +database: + mode: external + external: + host: mysql-primary.database.svc.cluster.local + port: 3306 + name: matomo + username: matomo + existingSecret: matomo-database + existingSecretPasswordKey: database-password + +matomo: + siteUrl: https://analytics.example.com + trustedHost: analytics.example.com + +persistence: + enabled: true + size: 50Gi + +archiver: + enabled: true + schedule: '5 * * * *' + +ingress: + enabled: true + ingressClassName: nginx + hosts: + - host: analytics.example.com + paths: + - path: / + pathType: Prefix + +networkPolicy: + enabled: true + egress: + enabled: true + extraEgress: + - to: + - ipBlock: + cidr: 10.80.0.0/16 + ports: + - protocol: TCP + port: 3306 +``` + +## Archiver + +Matomo recommends scheduled archive processing for production sites. The chart renders a Kubernetes CronJob when `archiver.enabled=true`: + +```yaml +archiver: + enabled: true + schedule: '5 * * * *' + concurrencyPolicy: Forbid + activeDeadlineSeconds: 7200 + extraArgs: [] +``` + +Set `matomo.siteUrl` to the public URL used by visitors. When it is empty, the chart derives an in-cluster service URL for the archiver. + +## Backups + +The chart does not render a dedicated backup job. Production backup plans must cover both runtime domains: + +- MySQL or MariaDB data, either through the external database platform or the bundled MySQL release. +- The Matomo application PVC at `/var/www/html`, which stores configuration, plugins, and generated assets. + +Take consistent backups before chart upgrades, Matomo upgrades, and plugin changes. For external databases, use the database platform's native backup and restore process and validate restore into a separate namespace. + +## External Secrets + +Use External Secrets Operator to project the database password into the Secret consumed by the Deployment: + +```yaml +mysql: + enabled: false + +database: + mode: external + external: + host: mysql.database.svc.cluster.local + username: matomo + existingSecret: matomo-database + existingSecretPasswordKey: database-password + +externalSecrets: + enabled: true + items: + - name: matomo-database + secretStoreRef: + name: cluster-secrets + kind: ClusterSecretStore + target: + name: matomo-database + data: + - secretKey: database-password + remoteRef: + key: production/matomo + property: database-password +``` + +## Networking + +Ingress: + +```yaml +ingress: + enabled: true + ingressClassName: nginx + hosts: + - host: analytics.example.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: matomo-tls + hosts: + - analytics.example.com +``` + +Gateway API: + +```yaml +gatewayAPI: + enabled: true + httpRoutes: + - name: public + parentRefs: + - name: public-gateway + namespace: gateway-system + hostnames: + - analytics.example.com + rules: + - matches: + - path: + type: PathPrefix + value: / +``` + +Dual-stack Service fields are available when the cluster supports them: + +```yaml +service: + ipFamilyPolicy: PreferDualStack + ipFamilies: + - IPv4 + - IPv6 +``` + +## Validation + +After deployment: + +```bash +helm test matomo -n matomo +kubectl get pods -n matomo -l app.kubernetes.io/name=matomo +kubectl logs -n matomo deploy/matomo --since=10m +kubectl get cronjob -n matomo +``` + +Also validate the Matomo installer, tracking endpoint, archive job completion, database connectivity, and reverse proxy host configuration. + +## Common Issues + +| Symptom | Likely Cause | Fix | +| ------------------------------------ | -------------------------------------------- | --------------------------------------------------- | +| Installer cannot connect to database | Host, Secret key, or network policy is wrong | Check database Secret, DNS, and egress rules. | +| Reports stay empty or slow | Archiver CronJob is disabled or failing | Enable `archiver.enabled` and inspect CronJob logs. | +| Redirects use the wrong hostname | Public URL or trusted host is incomplete | Set `matomo.siteUrl` and `matomo.trustedHost`. | +| Plugins disappear after restart | Application persistence is disabled | Enable `persistence.enabled`. | + + + +## Values + +| Parameter | Default | Description | +| ------------------------- | -------------------------- | ---------------------------------------------------------- | +| `image.repository` | `docker.io/library/matomo` | Official Matomo image repository. | +| `image.tag` | `5.11.2-apache` | Official Apache image tag. | +| `replicaCount` | `1` | Matomo web replica count. | +| `matomo.siteUrl` | `""` | Public URL used by archiver jobs. | +| `matomo.trustedHost` | `""` | Trusted host used for redirects behind a reverse proxy. | +| `database.mode` | `auto` | Database mode: `auto`, `external`, or `mysql`. | +| `mysql.enabled` | `true` | Deploy HelmForge MySQL dependency. | +| `persistence.enabled` | `true` | Persist `/var/www/html`. | +| `persistence.size` | `10Gi` | Matomo PVC size. | +| `archiver.enabled` | `true` | Render the `core:archive` CronJob. | +| `archiver.schedule` | `5 * * * *` | Archive CronJob schedule. | +| `ingress.enabled` | `false` | Render Ingress. | +| `gatewayAPI.enabled` | `false` | Render Gateway API HTTPRoute resources. | +| `externalSecrets.enabled` | `false` | Render ExternalSecret resources. | +| `networkPolicy.enabled` | `false` | Render NetworkPolicy. | +| `service.ipFamilyPolicy` | `""` | Kubernetes Service IP family policy. | +| `extraManifests` | `[]` | Additional Kubernetes manifests rendered with the release. | + +## Links + +- [Matomo](https://matomo.org/) +- [Matomo Docker image](https://hub.docker.com/_/matomo) +- [Chart source](https://github.com/helmforgedev/charts/tree/main/charts/matomo) diff --git a/src/pages/playground.astro b/src/pages/playground.astro index 97af6b51..2587bb4b 100644 --- a/src/pages/playground.astro +++ b/src/pages/playground.astro @@ -55,6 +55,8 @@ const siteSyncPlaygroundConfigs: Record = { kibana: 'src/data/playground-configs.ts', 'kubernetes-mcp-server': 'src/data/playground-configs.ts', langflow: 'src/data/playground-configs.ts', + clickhouse: 'src/data/playground-configs.ts', + matomo: 'src/data/playground-configs.ts', medikeep: 'src/data/playground-configs.ts', memcached: 'src/data/playground-configs.ts', memos: 'src/data/playground-configs.ts',