Install locally on minikube
Self-managed Materialize requires: a Kubernetes (v1.29+) cluster; PostgreSQL as a metadata database; and blob storage.
The following tutorial deploys the following components onto your local
minikube
:
- Materialize Operator using Helm into your local
minikube
cluster. - MinIO object storage as the blob storage for your Materialize.
- PostgreSQL database as the metadata database for your Materialize.
- Materialize as a containerized application into your local
minikube
cluster.
This tutorial is for local evaluation/testing purposes only.
- The tutorial uses sample configuration files that are for evaluation/testing purposes only.
- The tutorial uses a Kubernetes metrics server with TLS disabled. In practice, refer to your organization’s official security practices.
Prerequisites
minikube
Install minikube
.
Container or virtual machine manager
The following tutorial uses Docker
as the container or virtual machine
manager. To use another container or virtual machine manager as listed on the
minikube
documentation, refer to
the specific container/VM manager documentation.
Install Docker
.
Resource requirements for your container/virtual machine manager
For this local deployment, you will need the following Docker resource requirements:
- 3 CPUs
- 10GB memory
Helm 3.2.0+
If you don’t have Helm version 3.2.0+ installed, install. For details, see the Helm documentation.
kubectl
This tutorial uses kubectl
. To install, refer to the kubectl
documentationq.
For help with kubectl
commands, see kubectl Quick
reference.
Installation
-
Start Docker if it is not already running.
For this local deployment, you will need the following Docker resource requirements:
- 3 CPUs
- 10GB memory
-
Open a Terminal window.
-
Create a working directory and go to the directory.
mkdir my-local-mz cd my-local-mz
-
Create a minikube cluster.
minikube start
-
Add labels
materialize.cloud/disk=true
andworkload=materialize-instance
to theminikube
node (in this example, namedminikube
).kubectl label node minikube materialize.cloud/disk=true kubectl label node minikube workload=materialize-instance
Verify that the labels were successfully applied by running the following command:
kubectl get nodes --show-labels
-
To help you get started for local evaluation/testing, Materialize provides some sample configuration files. Download the sample configuration files from the Materialize repo:
mz_version=v0.130.4 curl -o sample-values.yaml https://raw.githubusercontent.com/MaterializeInc/materialize/refs/tags/$mz_version/misc/helm-charts/operator/values.yaml curl -o sample-postgres.yaml https://raw.githubusercontent.com/MaterializeInc/materialize/refs/tags/$mz_version/misc/helm-charts/testing/postgres.yaml curl -o sample-minio.yaml https://raw.githubusercontent.com/MaterializeInc/materialize/refs/tags/$mz_version/misc/helm-charts/testing/minio.yaml curl -o sample-materialize.yaml https://raw.githubusercontent.com/MaterializeInc/materialize/refs/tags/$mz_version/misc/helm-charts/testing/materialize.yaml
sample-values.yaml
: Used to configure the Materialize Operator.sample-postgres.yaml
: Used to configure PostgreSQL as the metadata database.sample-minio.yaml
: Used to configure minIO as the blob storage.sample-materialize.yaml
: Used to configure Materialize instance.
These configuration files are for local evaluation/testing purposes only and not intended for production use.
-
Install the Materialize Helm chart.
-
Add the Materialize Helm chart repository.
helm repo add materialize https://materializeinc.github.io/materialize
-
Update the repository.
helm repo update materialize
-
Install the Materialize Operator. The operator will be installed in the
materialize
namespace.helm install my-materialize-operator materialize/materialize-operator \ --namespace=materialize --create-namespace \ --version v25.1.2 \ --set operator.cloudProvider.region=minikube \ --set observability.podMetrics.enabled=true \ -f sample-values.yaml
-
Verify the installation and check the status:
kubectl get all -n materialize
Wait for the components to be ready and in the
Running
state:NAME READY STATUS RESTARTS AGE pod/my-materialize-operator-7c75785df9-6cn88 1/1 Running 0 9s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/my-materialize-operator 1/1 1 1 9s NAME DESIRED CURRENT READY AGE replicaset.apps/my-materialize-operator-7c75785df9 1 1 1 9s
If you run into an error during deployment, refer to the Troubleshooting guide.
-
-
Install PostgreSQL and minIO.
-
Use the
sample-postgres.yaml
file to install PostgreSQL as the metadata database:kubectl apply -f sample-postgres.yaml
-
Use the
sample-minio.yaml
file to install minIO as the blob storage:kubectl apply -f sample-minio.yaml
-
Verify the installation and check the status:
kubectl get all -n materialize
Wait for the components to be ready and in the
Running
state:NAME READY STATUS RESTARTS AGE pod/minio-777db75dd4-7cd77 1/1 Running 0 30s pod/my-materialize-operator-7c75785df9-6cn88 1/1 Running 0 88s pod/postgres-55fbcd88bf-zkwvz 1/1 Running 0 34s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/minio ClusterIP 10.98.114.67 <none> 9000/TCP 30s service/postgres ClusterIP 10.98.144.251 <none> 5432/TCP 34s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/minio 1/1 1 1 30s deployment.apps/my-materialize-operator 1/1 1 1 88s deployment.apps/postgres 1/1 1 1 34s NAME DESIRED CURRENT READY AGE replicaset.apps/minio-777db75dd4 1 1 1 30s replicaset.apps/my-materialize-operator-7c75785df9 1 1 1 88s replicaset.apps/postgres-55fbcd88bf 1 1 1 34s
-
-
Install the metrics service to the
kube-system
namespace.-
Add the metrics server Helm repository.
helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/
-
Update the repository.
helm repo update metrics-server
-
Install the metrics server to the
kube-system
namespace.! Important: This tutorial is for local evaluation/testing purposes only. For simplicity, the tutorial uses a Kubernetes metrics server with TLS disabled. In practice, refer to your organization’s official security practices.helm install metrics-server metrics-server/metrics-server \ --namespace kube-system \ --set args="{--kubelet-insecure-tls,--kubelet-preferred-address-types=InternalIP\,Hostname\,ExternalIP}"
You can verify the installation by running the following command:
kubectl get pods -n kube-system -l app.kubernetes.io/instance=metrics-server
Wait for the
metrics-server
pod to be ready and in theRunning
state:NAME READY STATUS RESTARTS AGE metrics-server-89dfdc559-jt94n 1/1 Running 0 14m
-
-
Install Materialize into a new
materialize-environment
namespace:-
Use the
sample-materialize.yaml
file to create thematerialize-environment
namespace and install Materialize:kubectl apply -f sample-materialize.yaml
-
Verify the installation and check the status:
kubectl get all -n materialize-environment
Wait for the components to be ready and in the
Running
state.NAME READY STATUS RESTARTS AGE pod/mz10wiu7fyr7-balancerd-fddc4bd7c-lwqmp 1/1 Running 0 19s pod/mz10wiu7fyr7-cluster-s2-replica-s1-gen-1-0 1/1 Running 0 26s pod/mz10wiu7fyr7-cluster-u1-replica-u1-gen-1-0 1/1 Running 0 25s pod/mz10wiu7fyr7-console-6cbcd997dc-95tf2 1/1 Running 0 12s pod/mz10wiu7fyr7-console-6cbcd997dc-bbm5h 1/1 Running 0 12s pod/mz10wiu7fyr7-environmentd-1-0 1/1 Running 0 32s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/mz10wiu7fyr7-balancerd ClusterIP None <none> 6876/TCP,6875/TCP 19s service/mz10wiu7fyr7-cluster-s2-replica-s1-gen-1 ClusterIP None <none> 2100/TCP,2103/TCP,2101/TCP,2102/TCP,6878/TCP 26s service/mz10wiu7fyr7-cluster-u1-replica-u1-gen-1 ClusterIP None <none> 2100/TCP,2103/TCP,2101/TCP,2102/TCP,6878/TCP 26s service/mz10wiu7fyr7-console ClusterIP None <none> 8080/TCP 12s service/mz10wiu7fyr7-environmentd ClusterIP None <none> 6875/TCP,6876/TCP,6877/TCP,6878/TCP 19s service/mz10wiu7fyr7-environmentd-1 ClusterIP None <none> 6875/TCP,6876/TCP,6877/TCP,6878/TCP 32s service/mz10wiu7fyr7-persist-pubsub-1 ClusterIP None <none> 6879/TCP 32s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/mz10wiu7fyr7-balancerd 1/1 1 1 19s deployment.apps/mz10wiu7fyr7-console 2/2 2 2 12s NAME DESIRED CURRENT READY AGE replicaset.apps/mz10wiu7fyr7-balancerd-fddc4bd7c 1 1 1 19s replicaset.apps/mz10wiu7fyr7-console-6cbcd997dc 2 2 2 12s NAME READY AGE statefulset.apps/mz10wiu7fyr7-cluster-s2-replica-s1-gen-1 1/1 26s statefulset.apps/mz10wiu7fyr7-cluster-u1-replica-u1-gen-1 1/1 26s statefulset.apps/mz10wiu7fyr7-environmentd-1 1/1 32s
If you run into an error during deployment, refer to the Troubleshooting guide.
-
-
Open the Materialize Console in your browser:
-
Find your console service name.
MZ_SVC_CONSOLE=$(kubectl -n materialize-environment get svc \ -o custom-columns="NAME:.metadata.name" --no-headers | grep console) echo $MZ_SVC_CONSOLE
-
Port forward the Materialize Console service to your local machine:1
( while true; do kubectl port-forward svc/$MZ_SVC_CONSOLE 8080:8080 -n materialize-environment 2>&1 | tee /dev/stderr | grep -q "portforward.go" && echo "Restarting port forwarding due to an error." || break; done; ) &
The command is run in background.
- To list the background jobs, usejobs
.
- To bring back to foreground, usefg %<job-number>
.
- To kill the background job, usekill %<job-number>
. -
Open a browser and navigate to http://localhost:8080.
💡 Tip: If you experience long loading screens or unresponsiveness in the Materialize Console, we recommend increasing the size of themz_catalog_server
cluster. Refer to the Troubleshooting Console Unresponsiveness guide. -
Next steps
-
From the Console, you can get started with the Quickstart.
-
To start ingesting your own data from an external system like Kafka, MySQL or PostgreSQL, check the documentation for sources.
Clean up
To delete the whole local deployment (including Materialize instances and data):
minikube delete
See also
-
The port forwarding command uses a while loop to handle a known Kubernetes issue 78446, where interrupted long-running requests through a standard port-forward cause the port forward to hang. The command automatically restarts the port forwarding if an error occurs, ensuring a more stable connection. It detects failures by monitoring for “portforward.go” error messages. ↩︎