Why I Ditched Kubernetes for Local Development

📅 April 27, 2026
👁 ... views

Every week in a Slack channel or Reddit thread, someone drops the unsolicited advice: “You should be using Kubernetes locally.”

They’re not evil people. They’re just solving a problem they have, not the problem I have.

I’ve run Kubernetes in production. I’ve debugged crashed pods at 2 AM, deciphered kubectl describe output until my eyes bled, and spent days tuning Helm charts for something that should have been a 20-line Docker Compose file.

Then I went back to Docker Compose for local development. Here’s why.

The Kubernetes Hype Cycle

Let me get this out of the way: Kubernetes is genuinely impressive technology. If you’re running microservices at scale, need rolling deployments with zero downtime, or are orchestrating hundreds of containers across multiple nodes — k8s is the right answer.

But here’s what happens in the dev community:

  1. Big tech blog posts about how they run k8s in production
  2. Devs conclude k8s must be the “professional” way
  3. They install Minikube or kind and try to run their 3-service app
  4. Two hours later, they’ve written more YAML than application code
  5. They either give up or spend the next 6 months maintaining their “simple” local setup

The tooling around local k8s has gotten better. KIND (Kubernetes IN Docker) exists. k3s is lightweight. Lens makes the dashboard tolerable. None of this changes the fundamental problem: local k8s adds massive complexity for zero benefit on most projects.

What Kubernetes Actually Solves

To understand why I ditched k8s locally, you need to understand what it actually solves:

Problems k8s is designed for:

  • Service-to-service load balancing across dozens of pods
  • Horizontal pod autoscaling based on CPU/memory metrics
  • Rolling deployments with zero-downtime updates
  • Secret management across distributed services
  • Cross-node networking in multi-node clusters
  • Self-healing when containers crash and need rescheduling

Problems k8s creates for local dev:

  • Every service needs a Deployment, Service, and usually an Ingress definition
  • kubectl commands are verbose and error-prone
  • Resource limits, health checks, liveness probes — boilerplate everywhere
  • Multiple config files per service vs. one docker-compose.yml
  • Your laptop becomes a k8s control plane (RAM usage: fun)
  • teammates need to install and configure k8s just to run the project

If you’re not hitting the “problems k8s solves” list, you’re paying the complexity tax for nothing.

What I Use Instead: Docker Compose (Done Right)

After the k8s experiment, I went back to Docker Compose. But not the naive version — I’ve learned to use the patterns that actually matter in production.

Here’s my current docker-compose.yml for a typical API project:

services:
  api:
    build:
      context: ./api
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://postgres:password@db:5432/myapp
      - REDIS_URL=redis://cache:6379
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    restart: unless-stopped

  db:
    image: postgres:16-alpine
    environment:
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=myapp
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  cache:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  migrate:
    build:
      context: ./api
      dockerfile: Dockerfile
    depends_on:
      db:
        condition: service_healthy
    command: npm run db:migrate
    restart: "no"

volumes:
  pgdata:

The key patterns you need:

  1. Health checks on every service — no startup race conditions
  2. depends_on with condition: service_healthy — waits for DB, not just “container started”
  3. Restart policies — containers that stay up, stay up
  4. restart: "no" for one-shot jobs like migrations — they shouldn’t restart on failure

This is production-adjacent. You can test health checks, verify startup ordering, and mirror this exactly in CI.

The Real Question to Ask

Before you reach for Kubernetes, ask yourself:

“What problem do I have that Docker Compose cannot solve?”

If the answer is “none” — and for 90% of projects, it is — you’re done. Use Compose.

If you need:

  • Multi-node simulation (for distributed systems debugging)
  • Kubernetes-specific features (CronJobs, StatefulSets, custom operators)
  • Production parity that genuinely requires k8s semantics

Then use kind or Minikube. But scope it to the specific thing you actually need to test.

The Counter-Argument (And Why It’s Wrong)

“But our production runs Kubernetes!”

Yes, and you should test against that production setup. But that doesn’t mean your local environment needs to be a k8s cluster. Here’s what you should actually be testing locally:

  • Your application’s behavior (does the code work?)
  • Service dependencies (does your API talk to the DB correctly?)
  • Health checks (does the service report healthy?)
  • Startup ordering (do things come up in the right order?)
  • Configuration (do your environment variables work?)

All of this works with Docker Compose. You don’t need pods, nodes, or kube-api to test your application code.

The k8s fans will say: “But you should test your Kubernetes manifests!”

Fair point. But those manifests should be tested in a test environment (CI), not necessarily on your laptop. Separate the concerns: local development is for writing application code, CI is for validating infrastructure.

Bottom Line

I spent 3 months running Kubernetes locally. It was technically interesting and practically useless for my workflow.

Docker Compose, used with proper health checks and startup ordering, handles every local development scenario I’ve encountered in 10 years of production code. It starts fast, it reads in one file, and everyone on the team can run it without a CS degree in cluster management.

Stop treating Kubernetes as the default for local development. Treat it as the power tool it is — reach for it when you actually need it.

What’s your local dev stack? Still fighting with k8s? Drop it in the comments — I’ve heard the other side of this argument and I’m open to being convinced.



📚 Continue Reading

Supporting the blog through affiliate links (at no extra cost to you):

💡

Enjoying the content? Here are tools I personally use and recommend:

  • 🌐 Hosting: Bluehost — what this blog runs on
  • 🛒 Tech Gear: My Amazon Store — keyboards, monitors, dev tools I use

Purchases through my links help keep this blog ad-free 💙

Enjoyed this post?

Subscribe to the newsletter or follow on YouTube for more dev content.

🎬 Watch Shorts