Metabase is an open-source BI tool for building charts and dashboards over MySQL, PostgreSQL, MongoDB, Redshift, and more. This guide deploys Metabase on Kubernetes, loads the Sakila sample dataset into MySQL, builds a dashboard, and secures it behind Nginx Ingress with cert-manager TLS.
Prerequisites: a Kubernetes cluster with
kubectl/helmconfigured, a Linux workstation, a reachable MySQL server, and a domain name.
Load the Sakila Sample Database
Sakila models a DVD rental store — films, actors, inventory, rentals.
$ sudo apt install zip -y
$ wget https://downloads.mysql.com/docs/sakila-db.zip
$ unzip sakila-db.zip
Enter fullscreen mode Exit fullscreen mode
Connect to your MySQL server (replace host/port/user):
$ mysql -h <HOST_ENDPOINT> -P <DATABASE_PORT> -u <ADMIN_USER> -p
Enter fullscreen mode Exit fullscreen mode
mysql> CREATE DATABASE sakila;
mysql> SOURCE sakila-db/sakila-schema.sql;
mysql> SOURCE sakila-db/sakila-data.sql;
Enter fullscreen mode Exit fullscreen mode
Deploy Metabase
$ nano metabase.yaml
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode
Your cloud provider may need a provider-specific LoadBalancer annotation here (e.g. to set the listener protocol) — check its Kubernetes docs if the default doesn't work.
$ kubectl apply -f metabase.yaml
$ kubectl get deployments
$ kubectl get services
Enter fullscreen mode Exit fullscreen mode
Wait for metabase-svc to get an EXTERNAL-IP (can take a few minutes), then visit http://<external-ip>:8080 to confirm the Metabase welcome page loads.
Connect Metabase to the Database
- Let's get started → pick language.
- Enter your name, email, company, and a password.
- Select your use case.
- Database engine: MySQL. Set a display name, then host/port/database/user/password.
- Connect Database → set data-sharing preference → Finish → Take me to Metabase.
Build a Dashboard
- + New → Dashboard, name it, Create.
- Add a chart → New SQL query, pick your database.
- Run:
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;
Enter fullscreen mode Exit fullscreen mode
- Run Query to preview results as a table.
- Visualization → Line → Done to switch to a line chart.
- Save, name the chart — it now appears in your dashboard.
Secure with Ingress + TLS
1. Switch the service off a public LoadBalancer:
$ kubectl patch svc metabase-svc -p '{"spec": {"type": "ClusterIP"}}'
$ kubectl get services
Enter fullscreen mode Exit fullscreen mode
2. Install Nginx Ingress:
$ helm install my-ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace
$ kubectl get services -n ingress-nginx
Enter fullscreen mode Exit fullscreen mode
Point your domain's A record at the Ingress controller's external IP.
3. Install cert-manager — check the releases page for the current version:
$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.17.0/cert-manager.yaml
Enter fullscreen mode Exit fullscreen mode
4. Create an Issuer:
$ nano cert-issuer.yaml
Enter fullscreen mode Exit fullscreen mode
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: [email protected]
privateKeySecretRef:
name: letsencrypt-private-key
solvers:
- http01:
ingress:
class: nginx
Enter fullscreen mode Exit fullscreen mode
$ kubectl apply -f cert-issuer.yaml
Enter fullscreen mode Exit fullscreen mode
5. Create the Ingress. Replace example.com:
$ nano ingress.yaml
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode
$ kubectl apply -f ingress.yaml
$ kubectl get ingress
Enter fullscreen mode Exit fullscreen mode
You'll briefly see a cm-acme-http-solver-* ingress handling the ACME challenge alongside ingress-metabase — once resolved, both show your controller's public IP.
6. Confirm the certificate is issued:
$ kubectl get certificate
Enter fullscreen mode Exit fullscreen mode
READY: True means you're set — visit https://example.com to reach Metabase over TLS.
Next Steps
Metabase is running on Kubernetes with a live dataset, a saved chart, and TLS via Ingress. From here:
- Connect additional databases and build cross-source dashboards
- Set up scheduled email/Slack reports from saved questions
- Add a
HorizontalPodAutoscalerif query load grows beyond a single replica
For the full guide, visit the original article on Vultr Docs.
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.