This guide walks through the complete DevOps pipeline I built for containerizing and deploying a Next.js application. No code dumps - just clear explanations of what each component does and how to use them.
Next.js App β Docker Container β GitHub Actions β GHCR β Kubernetes (Minikube)
# Install Node.js (for local development)
# Install Docker Desktop
# Install Minikube for local Kubernetes
# Install kubectl CLI toolnpm install # Install dependencies
npm run dev # Start development server
npm run build # Build for production
npm start # Start production serverAccess at: http://localhost:3000
I used a multi-stage build approach for optimal security and performance:
Stage 1: Dependencies - Install only production dependencies
Stage 2: Builder - Build the Next.js application
Stage 3: Runner - Create minimal final image with non-root user
# Build the image
docker build -t nextjs-app .
# Run locally
docker run -p 3000:3000 nextjs-app
# Pull my pre-built image
docker pull ghcr.io/neerajnakka/nextjs-app:latest- Trigger: On every push to
mainbranch - Checkout: Get the latest code
- Setup: Configure Docker Buildx for better builds
- Login: Authenticate with GitHub Container Registry
- Build & Push: Create and upload Docker image with proper tags
latest: Always points to most recent stable build- SHA tags: Unique identifier for each commit (
abc123def) - Branch tags: For testing feature branches
Create GitHub secret GHCR_PAT with write:packages permission
# Start your local Kubernetes cluster
minikube start
# Verify everything is running
minikube status
kubectl get nodesMy Kubernetes setup includes:
High Availability: 2 replicas - if one fails, traffic routes to the other
Resource Management: CPU and memory limits to prevent resource hogging
Health Monitoring:
- Liveness Probe: Checks if app is running (after 10s)
- Readiness Probe: Checks if app can accept traffic (after 5s)
Image Policy: Always pull to ensure latest version
NodePort Service: Exposes app on port 30001 across all cluster nodes
# Apply all Kubernetes configurations
kubectl apply -f k8s/
# Check deployment status
kubectl get deployments
kubectl get pods
kubectl get services# Get direct URL to your application
minikube service nextjs-service --url
# Output: http://192.168.49.2:30001
# Open this URL in your browser# Get cluster IP
minikube ip
# Output: 192.168.49.2
# Access at: http://192.168.49.2:30001# Forward local port to Kubernetes service
kubectl port-forward service/nextjs-service 8080:80
# Access at: http://localhost:8080# Check if pods are healthy
kubectl get pods -l app=nextjs
# View application logs
kubectl logs -l app=nextjs
# Check service details
kubectl describe service nextjs-service
# Monitor resource usage
kubectl top pods- Pods not starting: Check
kubectl describe pod <pod-name> - Image pull errors: Verify GHCR permissions
- Service not accessible: Ensure Minikube is running
- Health check failures: Check application logs
β
Security: Non-root user in containers
β
Reliability: Multiple replicas with health checks
β
Efficiency: Multi-stage Docker builds
β
Automation: Full CI/CD pipeline
β
Monitoring: Built-in health probes
β
Resource Management: CPU/Memory limits
β
Proper Tagging: Versioned container images
- Start Minikube:
minikube start - Deploy Application:
kubectl apply -f k8s/ - Get Access URL:
minikube service nextjs-service --url - Monitor:
kubectl get pods -l app=nextjs
This Next.js application is now running in a production-like Kubernetes environment with automated deployments, health monitoring, and proper resource management!