Deploy and Secure Metabase on Kubernetes
Metabase is an open-source business intelligence platform that allows you to create insightful dashboards and charts from your data. It supports popular databases such as MySQL, PostgreSQL, MongoDB, and Redshift. By deploying Metabase on Kubernetes, you can achieve scalable analytics in real time and facilitate data sharing across teams to improve collaboration and KPI tracking.
This guide explains how to deploy Metabase on a Kubernetes cluster. You will create a database with a sample dataset, install Metabase, connect it to your database, and visualize your data on a dashboard. Additionally, you will configure Nginx Ingress and TLS to expose Metabase securely through a domain name.
Prerequisites
Before starting, ensure the following requirements are met:
- An existing Kubernetes cluster.
- Access to a Linux-based workstation, such as Ubuntu.
- Access to a remote MySQL server reachable from your cluster.
- Kubectl configured to manage your cluster.
- Helm installed on your workstation.
- A registered domain name to use with Metabase.
Set Up a Sample Database
The Sakila sample database simulates a DVD rental store with data on films, actors, stores, and rentals. Follow these steps to configure Sakila for use with Metabase.
Install Unzip if not already available:
$ sudo apt install zip -y
Download the Sakila database archive:
$ wget https://downloads.mysql.com/docs/sakila-db.zip
Extract the Sakila archive:
$ unzip sakila-db.zip
The archive contains three files: sakila-schema.sql, sakila-data.sql, and sakila.mwb.
Log in to your MySQL server (replace placeholders with actual values):
$ mysql -h -P -u -p
Create the Sakila database:
mysql> CREATE DATABASE sakila;
Load the database structure:
mysql> SOURCE sakila-db/sakila-schema.sql;
Import the data into the database:
mysql> SOURCE sakila-db/sakila-data.sql;
Deploy Metabase on Kubernetes
Next, deploy Metabase on your Kubernetes cluster using a deployment file and load balancer service.
Create the deployment manifest:
$ nano metabase.yaml
Add the following configuration:
apiVersion: apps/v1
kind: Deployment
metadata:
name: metabase
spec:
selector:
matchLabels:
app: metabase
replicas: 1
template:
metadata:
labels:
app: metabase
spec:
containers:
- name: metabase
image: metabase/metabase:latest
ports:
- containerPort: 3000
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: metabase-svc
spec:
type: LoadBalancer
selector:
app: metabase
ports:
- name: http
port: 8080
targetPort: 3000
Apply the deployment:
$ kubectl apply -f metabase.yaml
Verify deployments and services:
$ kubectl get deployments
Check services for the external IP address:
$ kubectl get services
Access Metabase in your browser using the external IP:
Configure Metabase with the Sample Database
Follow these steps to connect Metabase with the Sakila database and create a dashboard:
- Click Let’s get started.
- Select your preferred language.
- Enter your details (name, email, company, and password).
- Select MySQL as your database engine.
- Provide database credentials and click Connect Database.
- Set your data-sharing preferences and click Finish.
- Click Take me to Metabase to open the dashboard.
Create a Metabase Dashboard
To create a new dashboard:
- Click + New → Dashboard.
- Fill in dashboard details and click Create.
- Add a chart → New SQL query → select your database.
Run the following SQL query to calculate total revenue per day:
SELECT CAST(payment_date AS DATE) AS payment_date, SUM(amount) AS total_revenue
FROM payment
GROUP BY CAST(payment_date AS DATE)
ORDER BY payment_date;
Click Run Query to view results, choose Visualization → Line, then Save your chart. Your dashboard will now show a line chart displaying daily revenue.
Secure Metabase with TLS Encryption
Secure the Metabase deployment by enabling TLS encryption using Nginx Ingress and Cert-Manager.
Change the service type to ClusterIP:
$ kubectl patch svc metabase-svc -p '{"spec": {"type": "ClusterIP"}}'
Install Nginx Ingress controller with Helm:
$ helm install my-ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace
Install Cert-Manager:
$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.17.0/cert-manager.yaml
Create an Issuer manifest:
$ nano cert-issuer.yaml
Add the following content:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: tls-certificate-issuer
namespace: default
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: abc@example.com
privateKeySecretRef:
name: letsencrypt-private-key
solvers:
- http01:
ingress:
class: nginx
Apply the Issuer configuration:
$ kubectl apply -f cert-issuer.yaml
Create and apply an Ingress manifest:
$ nano ingress.yaml
Add the following content (replace example.com with your domain):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-metabase
annotations:
cert-manager.io/issuer: tls-certificate-issuer
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: metabase-svc
port:
number: 8080
tls:
- hosts:
- example.com
secretName: my-webapp-tls
Apply the Ingress file:
$ kubectl apply -f ingress.yaml
Once issued, access Metabase securely via HTTPS:
Conclusion
You have successfully deployed Metabase in a Kubernetes cluster, integrated it with a sample database, and visualized data in dashboards. You also secured Metabase with TLS encryption through Nginx Ingress. Explore the official Metabase documentation for more advanced configuration and usage options.


