matomo-org / matomo-org/docker

Working example Kubernetes config

Open
#219 8 comments 1 reaction 0 assignees View on GitHub
Dominant language
Shell
Stars
1k
Forks
384
PR merge metrics
No merged PRs in 30d

Description

I had to piece together from the very weak Docker and Docker Compose examples (that are out of date and slightly incorrect/minimal), but got a proper install of this running today. Note, this config is running with Istio generating the HTTPS certificates and handling termination, so all hosting is done via port 80, as is typical behind a load balancer or k8s cluster. Here's the config, do whatever you will with it:

```
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: analytics
labels:
app: analytics
spec:
hosts:
- "analytics.yourdomainname.com"
gateways:
- istio-gw
http:
- match:
- uri:
prefix: /
route:
- destination:
host: analytics # this refers to a Service with name="analytics"
port:
number: 80
---
apiVersion: v1 # this one is exposed by the Istio VirtualService above
kind: Service
metadata:
name: analytics
labels:
app: analytics
spec:
ports:
- port: 80
name: http-web
protocol: TCP
targetPort: http-web
selector:
app: analytics # send traffic to the analytics pods
sessionAffinity: None
type: ClusterIP
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: analytics
labels:
app: analytics
spec:
serviceName: analytics
replicas: 1
updateStrategy:
type: RollingUpdate
selector:
matchLabels:
app: analytics
template:
metadata:
annotations:
sidecar.istio.io/inject: "false" # if this is true, https gets proxied and everything breaks
labels:
app: analytics
version: 1.0.0
spec:
containers:
- image: matomo:fpm-alpine
imagePullPolicy: Always
name: analytics
env:
- name: MATOMO_DATABASE_ADAPTER
value: mysql
- name: MATOMO_DATABASE_HOST
value: mysql
- name: MATOMO_DATABASE_TABLES_PREFIX
value: analytics
- name: MATOMO_DATABASE_USERNAME
value: youruser
- name: MATOMO_DATABASE_PASSWORD
value: yourpass
- name: MATOMO_DATABASE_DBNAME
value: analytics
resources:
limits:
cpu: "3.0"
memory: "3Gi"
requests:
cpu: "0.25"
memory: "250Mi"
volumeMounts:
- name: analytics-storage
mountPath: /var/www/html
- image: nginx:latest
name: nginx
volumeMounts:
- name: analytics-storage
mountPath: /var/www/html
readOnly: true
- name: analytics-configmap
mountPath: /etc/nginx/conf.d/default.conf
subPath: nginx.conf
ports:
- containerPort: 80
name: http-web
resources:
limits:
cpu: "3.0"
memory: "3Gi"
requests:
cpu: "0.25"
memory: "250Mi"
- image: mysql:5.7
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: yourrootpw
- name: MYSQL_DATABASE
value: analytics
- name: MYSQL_USER
value: youruser
- name: MYSQL_PASSWORD
value: yourpass
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: analytics-db
mountPath: /var/lib/mysql
- name: analytics-configmap
mountPath: /etc/mysql/conf.d/more.cnf
subPath: more.cnf
livenessProbe:
initialDelaySeconds: 10
timeoutSeconds: 10
periodSeconds: 30
failureThreshold: 5
tcpSocket:
port: mysql
readinessProbe:
initialDelaySeconds: 20
timeoutSeconds: 10
periodSeconds: 30
failureThreshold: 5
tcpSocket:
port: mysql
resources:
limits:
cpu: "3.0"
memory: "3Gi"
requests:
cpu: "0.25"
memory: "250Mi"
volumes:
- name: analytics-storage
persistentVolumeClaim:
claimName: analytics-storage
- name: analytics-db
persistentVolumeClaim:
claimName: analytics-db
- name: analytics-configmap
configMap:
name: analytics-configmap
items:
- key: nginx.conf
path: nginx.conf
- key: more.cnf
path: more.cnf
volumeClaimTemplates: # this automatically allocates storage via your-storage-class (NFS?)
- metadata:
name: analytics-storage
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "your-storage-class"
resources:
requests:
storage: 10Gi
- metadata:
name: analytics-db
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "your-storage-class"
resources:
requests:
storage: 20Gi
---
apiVersion: v1
kind: ConfigMap
metadata:
name: analytics-configmap
labels:
app: analytics
data:
more.cnf: |
[mysqld]
innodb_buffer_pool_size=256M
max_allowed_packet=64M
sql_mode=STRICT_ALL_TABLES
wait_timeout = 28800
interactive_timeout = 28800
nginx.conf: |
server {
listen [::]:80; # remove this if you don't want Matomo to be reachable from IPv6
listen 80;
server_name localhost;
access_log /dev/stdout;
error_log /dev/stdout;

add_header Referrer-Policy origin always; # make sure outgoing links don't show the URL to the Matomo instance
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;

root /var/www/html/;

index index.php;

## Begin - Index
## only allow accessing the following php files
location ~ ^/(index|matomo|piwik|js/index|plugins/HeatmapSessionRecording/configs)\.php {
# Choose either a socket or TCP/IP address
# fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
# fastcgi_pass unix:/var/run/php5-fpm.sock; #legacy
fastcgi_pass localhost:9000;

fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
fastcgi_param HTTP_PROXY ""; # prohibit httpoxy: https://httpoxy.org/
}

## deny access to all other .php files
location ~* ^.+\.php$ {
deny all;
return 403;
}

## serve all other files normally
location / {
try_files $uri $uri/ =404;
}

## disable all access to the following directories
location ~ ^/(config|tmp|core|lang) {
deny all;
return 403; # replace with 404 to not show these directories exist
}

location ~ /\.ht {
deny all;
return 403;
}

location ~ js/container_.*_preview\.js$ {
expires off;
add_header Cache-Control 'private, no-cache, no-store';
}

location ~ \.(gif|ico|jpg|png|svg|js|css|htm|html|mp3|mp4|wav|ogg|avi|ttf|eot|woff|woff2|json)$ {
allow all;
## Cache images,CSS,JS and webfonts for an hour
## Increasing the duration may improve the load-time, but may cause old files to show after an Matomo upgrade
expires 1h;
add_header Pragma public;
add_header Cache-Control "public";
}

location ~ ^/(libs|vendor|plugins|misc/user|node_modules) {
deny all;
return 403;
}

## properly display textfiles in root directory
location ~/(.*\.md|LEGALNOTICE|LICENSE) {
default_type text/plain;
}
}
# vim: filetype=nginx

```

Contributor guide

No contributing guide indexed for this repository

Research direction

No repository file or test is named. Start by reviewing the current Docker and Docker Compose examples, then compare them with the Kubernetes configuration in the issue and check whether Kubernetes or Istio examples already exist. Done should mean a maintainer-approved, current working example with a clearly documented place in the project.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, kubernetes, mysql, nginx
Domain
databases, devops, documentation, infrastructure
Issue type
Documentation
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.