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.
! Important:

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

  1. Start Docker if it is not already running.

    For this local deployment, you will need the following Docker resource requirements:

    • 3 CPUs
    • 10GB memory
  2. Open a Terminal window.

  3. Create a working directory and go to the directory.

    mkdir my-local-mz
    cd my-local-mz
    
  4. Create a minikube cluster.

    minikube start
    
  5. Add labels materialize.cloud/disk=true and workload=materialize-instance to the minikube node (in this example, named minikube).

    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
    
  6. 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.

  7. Install the Materialize Helm chart.

    1. Add the Materialize Helm chart repository.

      helm repo add materialize https://materializeinc.github.io/materialize
      
    2. Update the repository.

      helm repo update materialize
      
    3. 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
      
    4. 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.

  8. Install PostgreSQL and minIO.

    1. Use the sample-postgres.yaml file to install PostgreSQL as the metadata database:

      kubectl apply -f sample-postgres.yaml
      
    2. Use the sample-minio.yaml file to install minIO as the blob storage:

      kubectl apply -f sample-minio.yaml
      
    3. 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
      
  9. Install the metrics service to the kube-system namespace.

    1. Add the metrics server Helm repository.

      helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/
      
    2. Update the repository.

      helm repo update metrics-server
      
    3. 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 the Running state:

      NAME                             READY   STATUS    RESTARTS   AGE
      metrics-server-89dfdc559-jt94n   1/1     Running   0          14m
      
  10. Install Materialize into a new materialize-environment namespace:

    1. Use the sample-materialize.yaml file to create the materialize-environment namespace and install Materialize:

      kubectl apply -f sample-materialize.yaml
      
    2. 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.

  11. Open the Materialize Console in your browser:

    1. 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
      
    2. 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, use jobs.
      - To bring back to foreground, use fg %<job-number>.
      - To kill the background job, use kill %<job-number>.

    3. 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 the mz_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


  1. 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. ↩︎

Back to top ↑