Why Production Parity Matters Locally#
The most expensive bugs are the ones you find after deploying to production. A minikube cluster with default settings lacks ingress, metrics, and resource enforcement – so your app works locally and breaks in staging. The goal is to configure minikube so that anything that works on it has a high probability of working on a real cluster.
Choosing Your Local Kubernetes Tool#
Before configuring minikube, decide if it is the right tool.
| Tool | Best For | Trade-off |
|---|---|---|
| minikube | Full Kubernetes experience, addon ecosystem, multi-profile support | Heavier resource usage |
| kind | CI pipelines, testing controllers, multi-node clusters | No built-in addons, less production-like networking |
| k3s | Lightweight production clusters, edge, IoT | Removes some Kubernetes features (e.g., cloud provider integration) |
Use minikube when you want a single-node cluster that behaves like a managed Kubernetes service with ingress, metrics, and storage provisioning out of the box. Use kind when you need fast, disposable clusters in CI. Use k3s when you are deploying to actual hardware and want a lightweight distribution.
The Production Profile Start Command#
minikube start \
--profile=myproject \
--driver=docker \
--cpus=4 \
--memory=8192 \
--disk-size=40g \
--kubernetes-version=v1.29.2 \
--addons=metrics-server,ingress,storage-provisioner,registry,dashboardEvery flag here solves a specific production-parity problem:
--profile=myproject– Isolates this cluster entirely. You can runminikube start --profile=other-projectand have two separate clusters with separate contexts, namespaces, and addons. Profiles prevent one project’s experiments from breaking another.--driver=docker– On Apple Silicon, this ensures native ARM64 execution with no QEMU emulation. On Intel, it avoids VM overhead.--cpus=4 --memory=8192– Resource requests and limits in your pod specs only work when the node actually has resources to allocate. A 2CPU/4GB cluster will OOM-kill pods unpredictably. 4CPU/8GB handles a typical stack (app + database + monitoring).--disk-size=40g– Container images add up. A monitoring stack alone pulls several gigabytes of images.--kubernetes-version=v1.29.2– Pin the version to match your production cluster. API deprecations between versions cause real failures.--addons– These five addons close the biggest gaps between minikube and production.
Resource Allocation Guidance#
| Stack Complexity | CPUs | Memory | Example |
|---|---|---|---|
| Single app + database | 2 | 4 GB | API server + PostgreSQL |
| Full stack | 4 | 8 GB | App + DB + Redis + monitoring |
| Full stack + CI tooling | 6 | 12 GB | Above + ArgoCD + build jobs |
If your host machine has 16 GB of RAM, do not allocate more than 8 GB to minikube. Your host OS, Docker Desktop, and IDE need the rest.
What Each Addon Gives You#
metrics-server – Enables kubectl top pods and kubectl top nodes. Without this, Horizontal Pod Autoscalers do not work and you cannot see resource consumption. Production clusters always have this.
ingress – Deploys an nginx ingress controller. Without it, you are stuck with kubectl port-forward for every service. With it, you define Ingress resources exactly as you would in production.
storage-provisioner – Automatically creates PersistentVolumes when a PersistentVolumeClaim is created. Without this, StatefulSets hang waiting for storage that never appears.
registry – Runs a container registry inside minikube at localhost:5000. Push images here instead of using eval $(minikube docker-env) for a workflow closer to production image pipelines.
dashboard – The Kubernetes dashboard. Useful for visual debugging, optional for automated workflows.
Working with Profiles#
# List all profiles
minikube profile list
# Switch kubectl context to a profile
minikube profile myproject
# Stop a specific profile (preserves state)
minikube stop --profile=myproject
# Delete a profile entirely
minikube delete --profile=myprojectEach profile gets its own kubectl context automatically. When you run minikube start --profile=myproject, your ~/.kube/config gains a context named myproject that points to that cluster.
Verifying Your Setup#
After starting, confirm the addons are running:
# Check all system pods are healthy
kubectl get pods -n kube-system --context=myproject
# Verify metrics-server works
kubectl top nodes
# Verify ingress controller is running
kubectl get pods -n ingress-nginx
# Verify storage provisioner
kubectl get storageclass
# Should show "standard (default)" with provisioner "k8s.io/minikube-hostpath"Quick Reference#
| Task | Command |
|---|---|
| Start production profile | minikube start --profile=myproject --driver=docker --cpus=4 --memory=8192 --addons=metrics-server,ingress,storage-provisioner,registry |
| Check addon status | minikube addons list --profile=myproject |
| Enable addon later | minikube addons enable metrics-server --profile=myproject |
| Get ingress IP | minikube ip --profile=myproject |
| Open dashboard | minikube dashboard --profile=myproject |