Ditching the Cookie Banners: Run Plausible Analytics on Azure Kubernetes

Jeroen Bach

·

6 min read ·

For quite some time, I've been looking for ways to gather website analytics without showing those annoying consent banners. If you've ever wanted website analytics without compromising privacy or user experience, this article is for you.

In this guide, I'll introduce you to Plausible Analytics - a lightweight, open-source, privacy-focused alternative to Google Analytics - and walk you through setting it up on an affordable Kubernetes cluster in Azure.

What is Plausible.io?

Plausible.io is a simple yet powerful analytics tool designed with privacy in mind. Unlike Google Analytics, Plausible doesn't use cookies or collect personally identifiable information. As a result, you can skip the cookie consent banner altogether and still remain compliant with GDPR and other privacy laws.

It's a great option for websites that care about usability, performance, and respecting visitor privacy.

The best part? You can run it yourself. You can start with their hosted cloud version, which comes with a free trial — perfect if you want to test it out without any setup hassle. If you like what you see, you can either stick with their subscription or take full control by self-hosting it.

Self-hosting vs. Hosted Solution

Self-hosting is ideal if you're a developer like me and happen to have some extra Azure credit lying around. It gives you full control and can be quite cost-effective. But if that's not your situation, the hosted solution is probably the more economical and hassle-free choice.

Either way, Plausible makes it easy to get started — and in this article, I'll show you how to set it up yourself using Docker and Kubernetes on Azure.

Affordable Plausible.io Hosting with Azure Kubernetes

In this article, I'll show you the cheapest way to host Plausible.io on Azure Kubernetes Service (AKS).

To give you an idea of what to expect: running this setup for a full month costs me around €35 — and that includes daily incremental backups.

Azure Kubernetes costs for Plausible.io

This setup includes the following key components:

  • cert-manager - to manage SSL/TLS certificates automatically
  • Let's Encrypt - for issuing free, trusted SSL certificates
  • NGINX Ingress Controller - to handle routing and expose Plausible to the internet
  • Plausible.io - the privacy-friendly analytics platform we're deploying

Storage Tip: Use Ephemeral Disks for Cost Savings

When creating an AKS cluster, one of the main extra costs comes from the persistent OS disk that's created by default for each node.

To reduce costs, you can use ephemeral OS disks instead. These are stored directly on the VM's local storage and come at no additional cost. They're ideal for stateless workloads or setups where persistent storage is handled separately — like in this case, where we store Plausible's data on an attached volume.

If you go this route, make sure to check the maximum disk size allowed for your selected VM size. For example, the Standard_B2s VM size supports up to 30 GB of ephemeral storage — which is more than enough for storing the necessary Docker images.

In the step-by-step guide below, you can run the commands directly in Azure Cloud Shell.

Create cluster
#bash
RESOURCEGROUP=rg-plausible-westeu-prod
CLUSTERNAME=aks-plausible-westeu-prod
LOCATION=westeurope
VMSIZE=Standard_B2s
VMDISKSIZE=30 # Keep this to the max size the VM allows (this is the max of Standard_B2s)

# Create the resource group
az group create --name $RESOURCEGROUP --location $LOCATION

# Create the AKS cluster
az aks create --resource-group $RESOURCEGROUP --name $CLUSTERNAME \
  --node-vm-size $VMSIZE \
  --node-count 1 \
  --node-resource-group ${RESOURCEGROUP}-nodes \
  --load-balancer-sku basic \
  --generate-ssh-keys \
  --location $LOCATION \
  --node-osdisk-type Ephemeral \
  --node-osdisk-size $VMDISKSIZE

# Get the credentials for the AKS cluster (for the following steps)
az aks get-credentials --resource-group $RESOURCEGROUP --name $CLUSTERNAME

With the cluster up and running, the next step is to create a ClusterIssuer, which will automate the issuance of TLS certificates using Let's Encrypt and to set up an Ingress that will handle external traffic and route it to the correct service within the cluster.

Configure Ingress and TLS certificates
#bash
LETSENCRYPTEMAIL=[email protected] # <--- Change this to your email address

# Create the letsencrypt cluster issuers
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --set crds.enabled=true
kubectl create -f - <<EOF
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-production
  namespace: cert-manager
spec:
  acme:
    # The ACME server URL
    server: https://acme-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: ${LETSENCRYPTEMAIL}
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-production
    # Enable the HTTP-01 challenge provider
    solvers:
    - http01:
        ingress:
          class: nginx
EOF

# Install nginx ingress controller
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm upgrade --install \
  ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --set controller.service.type=LoadBalancer \
  --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \
  --set controller.service.externalTrafficPolicy=Local \
  --create-namespace

echo "Waiting for the external ip to be assigned to the ingress controller, once it is available you can stop this script"
kubectl get service --namespace ingress-nginx ingress-nginx-controller --output wide --watch

Wait for the external IP to become available. Once it appears, you can stop the script — your cluster is now fully set up to run services and expose them via that public IP address.

Next, head over to your DNS provider and create a DNS record pointing to this IP. For example, you could create a subdomain like plausible.yourdomain.com.

Now we're going to install Plausible on the cluster. In the configuration below, you'll see that we:

  • Persist the storage for both PostgreSQL and ClickHouse — this is where all your analytics data will be stored. This way you can easily back up your data and restore it if needed. It also allows the containers to be managed without losing data.
  • Annotate the Ingress with the ClusterIssuer we created earlier, so that it can automatically request and renew TLS certificates for us.
  • Connect Plausible to the Ingress, and specify the DNS name for public access.
CloudShell
#bash
PLAUSIBLE_DNS=plausible.yourdomain.com

# Deploy Plausible Analytics using Helm
helm repo add imio https://imio.github.io/helm-charts
helm repo update
helm upgrade --install plausible-analytics imio/plausible-analytics \
  --namespace plausible-analytics \
  --create-namespace \
  --version 0.3.3 \
  --set baseURL="http://${PLAUSIBLE_DNS}" \
  --set postgresql.primary.persistence.enabled=true \
  --set postgresql.primary.persistence.size=1Gi \
  --set clickhouse.persistence.enabled=true \
  --set clickhouse.persistence.size=8Gi \
  --set ingress.enabled=true \
  --set ingress.annotations."cert-manager\.io/cluster-issuer"="letsencrypt-production" \
  --set ingress.annotations."kubernetes\.io/ingress\.class"=nginx \
  --set ingress.annotations."kubernetes\.io/tls-acme"="\"true\"" \
  --set ingress.className=nginx \
  --set ingress.hosts[0]=${PLAUSIBLE_DNS} \
  --set ingress.paths.path=/ \
  --set ingress.tls[0].secretName=letsencrypt-production \
  --set ingress.tls[0].hosts[0]=${PLAUSIBLE_DNS}

# Monitor deployment progress
echo "Monitoring deployment progress..."
kubectl get pods -n plausible-analytics -w

After the script finishes, you should be able to access Plausible at the DNS name you configured — for example, plausible.yourdomain.com.

Plausible.io community setup screen

Conclusion

In this article, we've set up a cost-effective and privacy-friendly analytics solution using Plausible.io on Azure Kubernetes Service (AKS). By leveraging Kubernetes, we're able to scale, manage, and secure our analytics platform while staying compliant with privacy regulations — all without annoying cookie consent banners.

You learned how to:

  • Configure the cheapest possible AKS cluster using your Azure credits
  • Set up Ingress and TLS certificate automation using cert-manager and Let's Encrypt
  • Deploy and run Plausible.io with persistent storage for both PostgreSQL and ClickHouse

This setup provides valuable insights into website traffic, respects user privacy, and gives you full control over your data — all at a low monthly cost.

If you're looking for a lightweight, open-source alternative to Google Analytics, Plausible.io is definitely worth considering.

If you have any questions or need help along the way, feel free to reach out.

Happy tracking!