Overview
Deployed a NextJS portfolio application inside a private Kubernetes cluster using Minikube on a Hyper-V Ubuntu VM, with secure public access via a persistent Cloudflare Tunnel linked to a custom domain. This was an early Kubernetes experiment that validated the core concept before the later enterprise-grade system.
Key Components
- Kubernetes: Minikube running on a Hyper-V Ubuntu VM
- Ingress: NGINX Ingress Controller for in-cluster routing
- Public Access: Cloudflare Zero Trust Tunnel (no port forwarding required)
- CI/CD: GitHub Actions with a self-hosted runner on the VM
- Persistence: systemd services for auto-start of Minikube and Cloudflare Tunnel
Architecture
- NextJS app containerized and pushed to Docker Hub via GitHub Actions
- Kubernetes Deployment and Service resources manage the app pods
- NGINX Ingress routes traffic from the cluster to the app service
- Cloudflare Tunnel terminates public HTTPS traffic and forwards to the Ingress
- Custom domain mapped via Cloudflare DNS — no public IP exposure
CI/CD Flow
- Push to GitHub triggers the Actions workflow
- Self-hosted runner on the Ubuntu VM builds and pushes the Docker image
- Runner then applies updated Kubernetes manifests using
kubectl - Kubernetes performs a rolling update — zero downtime deployment
Skills Gained
- Kubernetes orchestration with Minikube on a local VM
- NGINX Ingress configuration and path-based routing
- Cloudflare Zero Trust tunneling and DNS management
- Self-hosted GitHub Actions runner setup and management
- systemd service configuration for reliable process management
- End-to-end CI/CD automation without cloud infrastructure costs