# Local Cluster with minikube

Learn how to provision minikube for local development and testing of FusionAuth kubernetes deployments.

> For the index of this section of the site, see [llms.txt](https://fusionauth.io/docs/llms.txt)

Having the capability to deploy applications in a local Kubernetes environment allows engineers to quickly develop, test, and demo without the operational overhead of a full-blown cluster. This is precisely what [minikube](https://minikube.sigs.k8s.io/docs) is designed for: it runs a single-node cluster on your machine.

This guide shows you how to install and start minikube, then deploy the PostgreSQL database and Elasticsearch service that FusionAuth needs. After that, you deploy FusionAuth itself with the [Deploy with k8s](https://fusionauth.io/docs/deploy/production/kubernetes/fusionauth-deployment.md) guide.

```mermaid
graph LR
    subgraph minikube
        fa[FusionAuth] -->|TLS| pg[(PostgreSQL)]
        fa -->|Basic authentication| es[(Elasticsearch)]
    end
```

The minikube cluster you will create.

## Requirements

Before you begin, you will need to have the following installed.

*   [Docker Desktop](https://docs.docker.com/get-docker/) - The container environment you will use to run minikube.
*   `helm` - Package manager used for installing and managing Kubernetes applications. The FusionAuth deployment guide uses a Helm chart to install FusionAuth. For more information, see [Installing Helm](https://helm.sh/docs/intro/install/).

*   `kubectl` - Command line tool that interacts with the Kubernetes API server and is useful for managing Kubernetes clusters. Before proceeding, follow the installation documentation that corresponds to your platform found [here](https://kubernetes.io/docs/tasks/tools/). Use a `kubectl` version within one minor version of your cluster's Kubernetes version.

## Install minikube

Navigate to [minikube start](https://minikube.sigs.k8s.io/docs/start/) and complete step one by selecting the options that apply to your local machine.

For example, on macOS, Homebrew is a popular **installer type**:

Install minikube

```shell
brew install minikube
```

### Start minikube

Since you will be deploying multiple applications, you will want to start minikube using some additional resource considerations.

Caution

Before proceeding, make sure Docker Desktop has sufficient resources allocated. These settings can be found in Docker Desktop by navigating to Settings -> Resources . You need to have at least as much memory allocated to Docker Desktop as you give to minikube below.

Start minikube by additionally specifying **cpus** and **memory**.

Start minikube

```shell
minikube start --cpus 4 --memory 5g
```

When the command finishes, it will configure `kubectl` to point to the minikube cluster. You can confirm this by checking the status:

Get minikube status

```shell
minikube status
```

Output

```plaintext
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
```

## Deploy PostgreSQL

This guide runs PostgreSQL from the official `postgres` image. When the database starts, it creates a self-signed certificate, so FusionAuth can connect to it over TLS with the settings in the deployment guide.

Note

The database keeps its data inside the container, so you lose the data when the pod restarts. This is fine for local testing. For anything else, use a managed database or a [PersistentVolume](https://kubernetes.io/docs/concepts/storage/persistent-volumes/).

First, store a password for the `postgres` superuser in a Secret. Choose your own password, and note it, because you will use it again when you deploy FusionAuth:

Create a Secret for the PostgreSQL superuser

```shell
kubectl create secret generic postgres-credentials --from-literal=password='<superuser-password>'
```

Then create a file named `postgres.yaml` with a Deployment that runs PostgreSQL and a Service that exposes it to the rest of the cluster:

PostgreSQL configuration

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:18.1-bookworm
          # creates a self-signed certificate so FusionAuth can connect over TLS
          command: ["bash", "-c"]
          args:
            - >-
              openssl req -x509 -newkey rsa:2048 -nodes -days 365 -subj "/CN=postgres"
              -keyout /tmp/server.key -out /tmp/server.crt &&
              chown postgres /tmp/server.key /tmp/server.crt && chmod 600 /tmp/server.key &&
              exec docker-entrypoint.sh postgres -c ssl=on -c ssl_cert_file=/tmp/server.crt -c ssl_key_file=/tmp/server.key
          env:
            - name: POSTGRES_USER
              value: postgres
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: postgres-credentials
                  key: password
          ports:
            - containerPort: 5432
          readinessProbe:
            exec:
              command: ["pg_isready", "-U", "postgres"]
            periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: postgres
spec:
  selector:
    app: postgres
  ports:
    - port: 5432
```

Apply the file:

Deploy PostgreSQL

```shell
kubectl apply -f ./postgres.yaml
```

## Deploy Elasticsearch

FusionAuth supports Elasticsearch `7.6.1` through `7.17.x`. This guide runs a single Elasticsearch `7.17` node with security enabled, so FusionAuth has to authenticate as the `elastic` user.

Store a password for the `elastic` user in a Secret, and note it as well:

Create a Secret for the elastic user

```shell
kubectl create secret generic elasticsearch-credentials --from-literal=password='<search-password>'
```

Then create a file named `elasticsearch.yaml`:

Elasticsearch configuration

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: elasticsearch
spec:
  replicas: 1
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      containers:
        - name: elasticsearch
          image: docker.elastic.co/elasticsearch/elasticsearch:7.17.29
          env:
            - name: discovery.type
              value: single-node
            - name: xpack.security.enabled
              value: "true"
            - name: ES_JAVA_OPTS
              value: -Xms512m -Xmx512m
            - name: ELASTIC_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: elasticsearch-credentials
                  key: password
          ports:
            - containerPort: 9200
          readinessProbe:
            exec:
              command: ["bash", "-c", "curl -sf -u \"elastic:$ELASTIC_PASSWORD\" localhost:9200/_cluster/health"]
            periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: elasticsearch
spec:
  selector:
    app: elasticsearch
  ports:
    - port: 9200
```

Apply the file:

Deploy Elasticsearch

```shell
kubectl apply -f ./elasticsearch.yaml
```

## Verify the Deployments

It may take a minute or two for the pods to reach a `READY` state. Check them with `kubectl`:

Get pods

```shell
kubectl get pods -o wide
```

Output

```plaintext
NAME                             READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
elasticsearch-5ccc6b7c77-vm76w   1/1     Running   0          38s   10.244.0.6   minikube   <none>           <none>
postgres-78cf4d89f8-ppkdj        1/1     Running   0          38s   10.244.0.5   minikube   <none>           <none>
```

When a [Pod](https://kubernetes.io/docs/concepts/workloads/pods/) is in a status of `READY`, it means that it is available to serve requests and should be added to load balancing pools of all matching services. You can read more about [Pod lifecycles here](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/).

Each Deployment has a [Service](https://kubernetes.io/docs/concepts/services-networking/service/) that exposes it to the rest of the cluster:

Get services

```shell
kubectl get services
```

Output

```plaintext
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
elasticsearch   ClusterIP   10.96.9.215    <none>        9200/TCP   38s
kubernetes      ClusterIP   10.96.0.1      <none>        443/TCP    58s
postgres        ClusterIP   10.96.179.62   <none>        5432/TCP   38s
```

The `kubernetes` Service directs traffic to the Kubernetes API server.

### Kubernetes DNS

Kubernetes assigns each Service a DNS name that other pods in the cluster can use:

*   `postgres.default.svc.cluster.local`
*   `elasticsearch.default.svc.cluster.local`

For more information, see the Kubernetes documentation for [DNS for Services and Pods](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/).

## Next Steps

You now are running all the necessary infrastructure to deploy FusionAuth to minikube. Next up, [Deploy FusionAuth in Kubernetes](https://fusionauth.io/docs/deploy/production/kubernetes/fusionauth-deployment.md). When you configure the chart in that guide, use these values:

*   **database.host**: `postgres.default.svc.cluster.local`
*   **database.rootUser.username**: `postgres`, with the PostgreSQL password you chose above as the superuser password
*   **search.host**: `elasticsearch.default.svc.cluster.local`
*   **search.protocol**: `http`, because this Elasticsearch node doesn't use a certificate
*   The search username `elastic`, with the Elasticsearch password you chose above

Related

[Deploy Microsoft Azure Kubernetes Service (AKS) Learn how to provision an AKS cluster in Microsoft Azure. dockerkubernetesk8s](https://fusionauth.io/docs/deploy/production/kubernetes/aks.md)

[Deploy Elastic Kubernetes Service (EKS) Learn how to provision an EKS cluster in AWS. dockerkubernetesk8s](https://fusionauth.io/docs/deploy/production/kubernetes/eks.md)

[Deploy Deploy with k8s Learn how to deploy FusionAuth in a Kubernetes Cluster. dockerkubernetesk8s](https://fusionauth.io/docs/deploy/production/kubernetes/fusionauth-deployment.md)

[Deploy Google Kubernetes Engine (GKE) Learn how to provision a GKE cluster in Google Cloud (GCP). dockerkubernetesk8s](https://fusionauth.io/docs/deploy/production/kubernetes/gke.md)
---

## Other pages in Kubernetes

> For the full index of this section, see [Deploy](https://fusionauth.io/docs/llms-deploy.txt).

- [Microsoft Azure Kubernetes Service (AKS)](https://fusionauth.io/docs/deploy/production/kubernetes/aks.md): Learn how to provision an AKS cluster in Microsoft Azure.
- [Elastic Kubernetes Service (EKS)](https://fusionauth.io/docs/deploy/production/kubernetes/eks.md): Learn how to provision an EKS cluster in AWS.
- [Deploy with k8s](https://fusionauth.io/docs/deploy/production/kubernetes/fusionauth-deployment.md): Learn how to deploy FusionAuth in a Kubernetes Cluster.
- [Google Kubernetes Engine (GKE)](https://fusionauth.io/docs/deploy/production/kubernetes/gke.md): Learn how to provision a GKE cluster in Google Cloud (GCP).
- [Kubernetes](https://fusionauth.io/docs/deploy/production/kubernetes.md): Learn how to deploy and test FusionAuth using Kubernetes.
