DEV Community

Cover image for Deploying NGINX on Minikube Using Helm
Krisha Arya
Krisha Arya

Posted on

Deploying NGINX on Minikube Using Helm

Environment Details

  • OS: Windows 11
  • Container Runtime: Docker Desktop (Linux containers)
  • Kubernetes: Minikube
  • Package Manager: Helm

Objective

  • Install Helm on Windows
  • Start Minikube cluster
  • Create a Helm chart
  • Deploy NGINX using Helm
  • Expose the application using NodePort
  • Verify application internally and externally
  • Understand why some commands fail and alternatives are used

Installing Helm on Windows

Helm is a package manager for Kubernetes, used to deploy applications using reusable charts.

Method 1: Install using Winget

winget install Helm.Helm
Enter fullscreen mode Exit fullscreen mode

📌 Why this method?

  • Simplest and fastest
  • Automatically adds Helm to PATH
  • Recommended for beginners

Method 2: Manual Installation (Alternative)

Download Helm binary:

https://get.helm.sh/helm-v4.1.0-windows-amd64.zip
Enter fullscreen mode Exit fullscreen mode

Extract it and place in:

C:\helm
Enter fullscreen mode Exit fullscreen mode

Add Helm to PATH:

$env:Path += ";C:\helm"
Enter fullscreen mode Exit fullscreen mode

Verify Helm Installation

helm version
Enter fullscreen mode Exit fullscreen mode

✔ Confirms Helm is installed and accessible

Starting Minikube Cluster

Helm works on top of Kubernetes, so Minikube must be running first.

Start Minikube

minikube start --driver=docker
Enter fullscreen mode Exit fullscreen mode

📌 Why Docker driver?

  • Best supported on Windows
  • Lightweight and stable

Possible Errors are:
1) Starting Minikube — Initial Failure
❌ Command
minikube start

❌ Error
PROVIDER_DOCKER_NOT_RUNNING
deadline exceeded running "docker version"

📌 Reason

Minikube is configured to use the Docker driver, but:
Docker Engine was not running.
OR Docker context was incorrect.
Minikube cannot create a Kubernetes cluster without Docker running.

2) Fixing Docker Environment
✅ Step 1: Remove incorrect Docker host variable
Remove-Item Env:DOCKER_HOST

📌 Why?
Sometimes Docker tools inherit a stale DOCKER_HOST variable, which breaks communication with Docker Desktop.

✅ Step 2: Verify variable is removed
echo $Env:DOCKER_HOST

Expected output:
(empty)

✅ Step 3: Switch Docker context
docker context use desktop-linux

📌 Why?
Minikube on Windows requires Linux containers, not Windows containers.

3) Pulling Kubernetes Images (Optional but Used Here)

You manually pulled Kubernetes images:

docker pull registry.k8s.io/kube-apiserver:v1.34.0
docker pull registry.k8s.io/kube-controller-manager:v1.34.0
docker pull registry.k8s.io/kube-scheduler:v1.34.0
docker pull registry.k8s.io/kube-proxy:v1.34.0
docker pull registry.k8s.io/coredns/coredns:v1.12.1
docker pull registry.k8s.io/etcd:3.6.4-0
docker pull registry.k8s.io/pause:3.10.1
docker pull docker.io/kicbase/stable:v0.0.48

📌 Why this was done

Minikube had network trouble reaching registry.k8s.io
Pre-pulling images avoids download failure inside the Minikube container

Check Cluster Status

kubectl get nodes
Enter fullscreen mode Exit fullscreen mode

Expected:

STATUS: Ready
Enter fullscreen mode Exit fullscreen mode

4) Starting Minikube Successfully
✅ Command Used
minikube start --driver=docker --force

📌 Why --force?

Skips some validations
Useful when Docker/network warnings exist
Allows Minikube to fall back to alternative image sources

Creating a Helm Chart

Helm charts provide a template-based way to deploy applications.


Create Chart

helm create my-first-chart
Enter fullscreen mode Exit fullscreen mode

📌 What this does

  • Creates a complete application structure
  • Includes Deployment, Service, and configuration templates

Chart Structure

my-first-chart/
├── charts/
├── templates/
├── Chart.yaml
├── values.yaml
Enter fullscreen mode Exit fullscreen mode

Editing values.yaml

values.yaml contains default configuration values for the chart.

✅ Open file

notepad values.yaml
Enter fullscreen mode Exit fullscreen mode

✅ Replace content with below one.

replicaCount: 1

image:
  repository: nginx
  pullPolicy: IfNotPresent
  tag: "latest"

imagePullSecrets: []

nameOverride: ""
fullnameOverride: ""

serviceAccount:
  create: true
  automount: true
  annotations: {}
  name: ""

podAnnotations: {}
podLabels: {}

podSecurityContext: {}
securityContext: {}

service:
  type: NodePort
  port: 80

ingress:
  enabled: false
  className: ""
  annotations: {}
  hosts: []
  tls: []

# THIS BLOCK FIXES YOUR ERROR
httpRoute:
  enabled: false
  annotations: {}
  parentRefs: []
  hostnames: []
  rules: []

resources: {}

livenessProbe:
  httpGet:
    path: /
    port: http

readinessProbe:
  httpGet:
    path: /
    port: http

autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 10
  targetCPUUtilizationPercentage: 80

volumes: []
volumeMounts: []

nodeSelector: {}
tolerations: []
affinity: {}
Enter fullscreen mode Exit fullscreen mode

📌 Why NodePort?

  • Easy exposure in Minikube
  • No Ingress needed initially
  • Suitable for learning/testing

Installing the Helm Chart

✅ Install Command

helm install nginx-release .
Enter fullscreen mode Exit fullscreen mode

📌 What happens

  • Helm renders templates
  • Kubernetes objects are created:

    • Deployment
    • Service
    • Pod

Verifying Deployment

🔍 Check Pods

kubectl get pods
Enter fullscreen mode Exit fullscreen mode

Expected:

STATUS: Running
Enter fullscreen mode Exit fullscreen mode

🔍 Check Service

kubectl get svc nginx-release-my-first-chart
Enter fullscreen mode Exit fullscreen mode

Expected:

TYPE: NodePort
PORT: 80:<nodePort>
Enter fullscreen mode Exit fullscreen mode

Getting Node IP & NodePort (Manual Way)

$env:NODEIP = kubectl get nodes -o jsonpath="{.items[0].status.addresses[0].address}"
$env:NODEPORT = kubectl get svc nginx-release-my-first-chart -o jsonpath="{.spec.ports[0].nodePort}"
echo "http://$env:NODEIP`:$env:NODEPORT"
Enter fullscreen mode Exit fullscreen mode

📌 Why this is done

  • NodePort services are accessed via:
  http://<NodeIP>:<NodePort>
Enter fullscreen mode Exit fullscreen mode

Internal Connectivity Test (From Inside Cluster)

Possible errors are:

❌ BusyBox Test (May Fail)

kubectl run test --rm -it --image=busybox -- wget -qO- nginx-release-my-first-chart
Enter fullscreen mode Exit fullscreen mode

❌ Sometimes fails due to:

  • Limited networking tools
  • DNS issues in BusyBox

✅ Correct Alternative (Curl Image)

kubectl run test --rm -it --image=curlimages/curl --restart=Never -- curl http://nginx-release-my-first-chart
Enter fullscreen mode Exit fullscreen mode

✔ Output:

Welcome to nginx!
Enter fullscreen mode Exit fullscreen mode

📌 Why curl image works

  • Built specifically for HTTP testing
  • Reliable DNS + networking

Accessing Service Using Minikube (Recommended Way)

✅ Command

minikube service nginx-release-my-first-chart
Enter fullscreen mode Exit fullscreen mode

📌 What this does

  • Automatically fetches NodePort
  • Creates a tunnel (required for Docker driver on Windows)
  • Opens browser with correct URL

Summary of Errors & Fixes

Error Reason Fix
Docker not running Docker Desktop stopped Restart Docker
BusyBox timeout Image limitations Use curl image
PowerShell -- error Linux syntax used Use single-line command
NodePort not opening Docker driver limitation Use minikube service

Key Learnings (Beginner Friendly)

  • Helm simplifies Kubernetes deployments
  • values.yaml controls app behavior
  • NodePort is easiest exposure method in Minikube
  • Docker driver needs tunnel for service access
  • Not all test images behave the same

Conclusion

You successfully:

  • Installed Helm
  • Created a Helm chart
  • Deployed NGINX using Helm
  • Exposed it via NodePort
  • Verified access internally and externally

Stay tuned for next kubernetes topic ! 😊

Top comments (2)

Collapse
 
kedar7 profile image
Kedar Kulkarni

Great! How much space is needed for this setup?

Collapse
 
krisha_arya_55 profile image
Krisha Arya

Thanks for commenting! For deploying NGINX on Minikube using Helm, approximately 6–8 GB of free disk space is sufficient. This includes space for Docker, Minikube, Kubernetes components, Helm, and the NGINX container image. 😊