How to Use Local Docker Images with Minikube
When developing applications with Kubernetes locally using Minikube, you often need to use Docker images that you've built on your local machine. By default, Minikube runs in its own Docker environment, which means it can't access images built in your host Docker daemon. This guide covers several methods to make your local images available to Minikube.
Prerequisites
You'll need Minikube and Docker installed on your system, along with kubectl configured to work with your Minikube cluster. Basic knowledge of Docker and Kubernetes concepts is helpful.
Method 1: Using Minikube's Docker Environment
The most straightforward approach is to build your images directly in Minikube's Docker environment using the docker-env
command:
# Point your shell to Minikube's Docker daemon
eval $(minikube docker-env)
# Now build your image
docker build -t my-app:latest .
# Verify the image is available in Minikube
docker images | grep my-app
After running eval $(minikube docker-env)
, your Docker commands will execute inside Minikube's Docker environment. Any images you build will be directly available to Kubernetes pods.
Important: This setting only affects your current shell session. Open a new terminal if you want to return to using your host Docker daemon.
Method 2: Loading Images into Minikube
If you've already built images on your host system, you can load them into Minikube using the minikube image load
command:
# Build image on host
docker build -t my-app:latest .
# Load the image into Minikube
minikube image load my-app:latest
# Verify the image was loaded
minikube image ls | grep my-app
This method is useful when you want to keep your host Docker environment separate from Minikube's environment.
Method 3: Using a Local Registry
For more complex development workflows, you can set up a local Docker registry accessible to Minikube:
# Start a local registry
docker run -d -p 5000:5000 --name registry registry:2
# Build and tag your image for the local registry
docker build -t localhost:5000/my-app:latest .
# Push the image to the local registry
docker push localhost:5000/my-app:latest
# Configure Minikube to use insecure registries
minikube start --insecure-registry="localhost:5000"
Now you can reference the image as localhost:5000/my-app:latest
in your Kubernetes manifests.
Configuring Kubernetes Manifests
When using local images, you need to configure your Kubernetes deployments properly to prevent Kubernetes from trying to pull images from remote registries:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 1
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:latest
imagePullPolicy: Never # Important: prevents pulling from remote registry
ports:
- containerPort: 8080
The imagePullPolicy: Never
setting ensures Kubernetes uses the local image and doesn't attempt to pull from a remote registry.
Alternative Pull Policies
Understanding image pull policies is crucial for working with local images:
# Never pull, use local image only
imagePullPolicy: Never
# Pull only if image doesn't exist locally
imagePullPolicy: IfNotPresent
# Always pull from registry (default for :latest tag)
imagePullPolicy: Always
For development with local images, use Never
or IfNotPresent
to avoid unnecessary registry pulls.
Automating the Workflow
Create a script to streamline the build and deployment process:
#!/bin/bash
# deploy-local.sh
set -e
IMAGE_NAME="my-app"
IMAGE_TAG="latest"
echo "Setting up Minikube Docker environment..."
eval $(minikube docker-env)
echo "Building Docker image..."
docker build -t ${IMAGE_NAME}:${IMAGE_TAG} .
echo "Deploying to Kubernetes..."
kubectl apply -f k8s/
echo "Waiting for deployment to be ready..."
kubectl wait --for=condition=available --timeout=300s deployment/${IMAGE_NAME}
echo "Getting service information..."
kubectl get services
echo "Deployment complete!"
Make the script executable and run it:
chmod +x deploy-local.sh
./deploy-local.sh
Using Docker Compose for Local Development
For complex applications, you might want to use Docker Compose alongside Minikube:
# Use host Docker for Docker Compose
unset DOCKER_TLS_VERIFY
unset DOCKER_HOST
unset DOCKER_CERT_PATH
unset MINIKUBE_ACTIVE_DOCKERD
# Run your development stack
docker-compose up -d
# Switch back to Minikube for Kubernetes testing
eval $(minikube docker-env)
# Build and deploy to Kubernetes
docker build -t my-app:latest .
kubectl apply -f k8s/
Troubleshooting Common Issues
Problem: Image not found in Minikube
Solution: Verify you're using Minikube's Docker environment:
# Check current Docker context
docker context show
# Ensure you're using Minikube's Docker
eval $(minikube docker-env)
docker images
Problem: Pod fails with ImagePullBackOff
Solution: Check the image pull policy and image availability:
# Check pod events
kubectl describe pod <pod-name>
# Verify image exists in Minikube
minikube ssh
docker images
Problem: Changes not reflected in pods
Solution: Ensure you're rebuilding in the correct environment and restarting pods:
# Rebuild in Minikube environment
eval $(minikube docker-env)
docker build -t my-app:latest .
# Delete pods to force recreation
kubectl delete pods -l app=my-app
Working with Multiple Images
For applications with multiple services, you can automate the entire build process:
#!/bin/bash
# build-all.sh
SERVICES=("frontend" "backend" "worker")
eval $(minikube docker-env)
for service in "${SERVICES[@]}"; do
echo "Building $service..."
docker build -t $service:latest ./$service/
done
echo "All images built successfully!"
minikube image ls
Performance Optimization
To speed up the development cycle, use Docker build caching effectively:
# Use BuildKit for faster builds
export DOCKER_BUILDKIT=1
# Build with cache mount for dependencies
eval $(minikube docker-env)
docker build \
--cache-from my-app:latest \
-t my-app:latest \
.
Cleaning Up Resources
Regularly clean up unused images to free up space in Minikube:
# Remove unused images in Minikube
eval $(minikube docker-env)
docker image prune -f
# Remove unused containers
docker container prune -f
# Check disk usage
minikube ssh
df -h
Persistent Development Setup
Add these aliases to your shell configuration for easier development:
# Add to ~/.zshrc or ~/.bashrc
alias mk-env='eval $(minikube docker-env)'
alias mk-build='eval $(minikube docker-env) && docker build -t'
alias mk-deploy='kubectl apply -f k8s/ && kubectl rollout restart deployment'
# Usage examples:
# mk-env
# mk-build my-app:latest .
# mk-deploy
Integration with IDEs
Many IDEs can be configured to work with Minikube's Docker environment. For Visual Studio Code with the Docker extension:
- Set the Docker environment variables in your terminal
- Launch VS Code from that terminal:
code .
- The Docker extension will use Minikube's Docker daemon
Next Steps
Now that you can use local Docker images with Minikube, consider learning about:
- Setting up continuous integration with Minikube
- Using Helm charts for complex deployments
- Implementing health checks and monitoring
- Working with persistent volumes in Minikube
- Debugging applications running in Kubernetes
Found an issue?