Getting Started with Minikube

Last updated: April 13, 2025

1. Introduction: What is Minikube?

Minikube is a tool that makes it easy to run Kubernetes locally. It runs a single-node Kubernetes cluster inside a virtual machine (VM), Docker container, or bare-metal on your personal computer. This is invaluable for developers who want to experiment with Kubernetes or develop applications targeting Kubernetes without needing access to a full-blown cloud cluster.

Minikube simplifies managing the cluster lifecycle (start, stop, delete) and accessing Kubernetes features.

2. Prerequisites

  • 2 CPUs or more
  • 2GB of free memory or more
  • 20GB of free disk space or more
  • Internet connection
  • A container or virtual machine manager, such as Docker (Recommended), HyperKit, Hyper-V, KVM, VirtualBox, Podman, or QEMU.
  • Basic understanding of Docker and containers. See our Docker Commands Guide.

3. Installation

3.1 Installation Options

Follow the official installation guide for your OS on the Minikube website. Common methods include:

  • macOS: brew install minikube
  • Linux (binary): Download and install the binary.
  • Windows (binary/choco/winget): Download the .exe, or use choco install minikube or winget install Kubernetes.minikube.

3.2 Installing kubectl

kubectl is the CLI for interacting with Kubernetes. Install it following the official Kubernetes documentation.

# Verify kubectl installation
kubectl version --client

4. Starting Your Cluster

Start your local Kubernetes cluster using Minikube:

# Start using the default driver (often Docker)
minikube start

# Or specify a driver explicitly
minikube start --driver=docker

The first start downloads necessary components and might take a few minutes.

5. Building Your Application Image

Kubernetes runs applications packaged as container images (usually Docker images). Before deploying your compiled project, you need to create an image for it.

5.1 Creating a Dockerfile

A Dockerfile is a text file containing instructions to build a Docker image. Create a file named Dockerfile in your project's root directory.

Example Dockerfile (Simple Node.js App):

# Use an official Node.js runtime as a parent image
FROM node:18-alpine

# Set the working directory in the container
WORKDIR /usr/src/app

# Copy package.json and package-lock.json (if available)
COPY package*.json ./

# Install app dependencies
RUN npm ci --only=production

# Bundle app source inside the Docker image
COPY . .

# Specify the command to run on container start
CMD [ "node", "server.js" ]

Adapt this template for your specific application (e.g., using a Rust base image, copying compiled binaries, setting different commands).

5.2 Building the Image

Use the docker build command to create the image from your Dockerfile. Give it a meaningful tag (e.g., my-app:v1).

docker build -t my-app:v1 .

The . indicates the build context is the current directory.

5.3 Making the Image Available to Minikube

Minikube runs its own isolated environment (VM or container). It doesn't automatically see images built directly on your host machine's Docker daemon unless configured to do so.

  • Option 1 (Recommended): Use Minikube's Docker Daemon: Configure your terminal to use Minikube's internal Docker daemon before building.
    # Point your terminal's Docker client to Minikube's daemon
    eval $(minikube -p minikube docker-env)
    
    # NOW build your image - it will be available inside Minikube
    docker build -t my-app:v1 .
    
    # To switch back to your host's Docker daemon later:
    eval $(minikube -p minikube docker-env -u)
  • Option 2: Push to a Registry: Push your image to a container registry (like Docker Hub, GCR, ECR, etc.) and configure Kubernetes to pull from there. This is closer to a production workflow but adds complexity for local development.
    # Tag the image for your registry
    docker tag my-app:v1 your-dockerhub-username/my-app:v1
    
    # Log in to the registry
    docker login
    
    # Push the image
    docker push your-dockerhub-username/my-app:v1
  • Option 3: Load Image Directly: Load an image already built on your host into Minikube.
    minikube image load my-app:v1

For local development, Option 1 is often the most convenient.

6. Deploying Your Application

Now, instead of deploying a generic nginx image, we'll deploy the custom my-app:v1 image we built.

6.1 Creating a Deployment Manifest

Create a file named deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment
spec:
  replicas: 1 # Start with one instance
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app-container
        image: my-app:v1 # Use the image you built
        imagePullPolicy: IfNotPresent # Important for local images! Tells k8s not to pull if image exists locally in Minikube
        ports:
        - containerPort: 3000 # Port your application listens on INSIDE the container

Key changes:

  • image: my-app:v1: Points to your custom image. If you pushed to a registry, use the full registry path (e.g., your-dockerhub-username/my-app:v1).
  • imagePullPolicy: IfNotPresent: Crucial when using images built directly into Minikube's Docker environment (Option 1 above). Without this, Kubernetes might try (and fail) to pull the image from an external registry.
  • containerPort: Make sure this matches the port your application listens on.

6.2 Creating a Service Manifest

Create a file named service.yaml to expose your deployment:

apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  type: LoadBalancer # Use LoadBalancer for easy access via minikube service
  selector:
    app: my-app # Selects Pods managed by our Deployment (matches labels)
  ports:
    - protocol: TCP
      port: 80       # Port the service will be available on *within* the cluster
      targetPort: 3000 # Port your container listens on (must match containerPort in Deployment)

Key points:

  • selector: app: my-app: Connects the Service to the Pods created by the Deployment via labels.
  • type: LoadBalancer: Makes Minikube assign an external IP (accessible via minikube service).
  • port: 80: The port the service listens on *inside* the Kubernetes cluster network.
  • targetPort: 3000: The port your application container is actually listening on.

6.3 Applying the Manifests

Use kubectl to create the resources defined in the YAML files:

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

6.4 Accessing Your Application

Check the status and access your running application:

# Check deployment status
kubectl get deployments

# Check pod status
kubectl get pods

# Check service status
kubectl get services

# Access the service via Minikube's tunnel (run in a separate terminal or wait for URL)
minikube service my-app-service

This command should provide a URL (like http://192.168.X.X:YYYY) or open your browser directly to your running application.

7. Interacting with Your Cluster

7.1 Basic kubectl Commands

Use kubectl to inspect the state:

# Check cluster status and kubectl configuration
minikube status
kubectl config current-context # Should show 'minikube'
kubectl cluster-info

# Get list of nodes
kubectl get nodes

# Get list of pods, services, deployments in the default namespace
kubectl get pods,svc,deployments

7.2 Accessing the Kubernetes Dashboard

minikube dashboard

8. Managing the Minikube Cluster

Common management commands:

minikube stop   # Stop the cluster
minikube start  # Start again
minikube delete # Delete the cluster completely
minikube ip     # Get cluster IP
minikube ssh    # SSH into the node

9. Conclusion

Minikube is an excellent tool for running Kubernetes locally. By understanding how to build a Docker image for your application using a Dockerfile and how to make that image accessible to Minikube, you can easily deploy and test your own compiled projects in a realistic Kubernetes environment. Using declarative YAML manifests for Deployments and Services provides a structured way to define and manage your application within the cluster.

External Resources