2931 words
15 minutes

Kubernetes on Your Laptop — No Cloud, No Boring Docs, Just Magic

Cover image for Kubernetes on Your Laptop — No Cloud, No Boring Docs, Just Magic

Hey there, tech goddess (or just someone who’s allergic to boring docs 👀)

You’ve probably heard of Kubernetes, but every tutorial starts with “cluster,” “orchestration,” and “in the cloud”?

😩 No thanks.

But what if I told you that you could launch your own website in Kubernetes, right on your laptop, set up environment variables, pass in secrets — step by step, no AWS, no tears, no PhD required?

Docker, Minikube, kubectl, Pod, Deployment, ConfigMap, Secret — all of it. I’ll walk you through everything.

You just open VS Code, copy a few commands — and boom: a real cluster,spinning, working, and doing your bidding like a true DevOps enchantress. Enough theory — let’s do some hands-on magic.

No AWS, no signups, no credit cards — just you, your laptop, and your curiosity. 🚀


Step 1 — Installing Docker (and figuring out why you even need it)#

Scene 1: “What even is Docker?”#

Imagine you’re trying to run an app. It works perfectly for your friend on Windows, but not for you on a Mac. She’s on Windows, you’re on a Mac. It needs a bunch of libraries you don’t have.

🎯 The fix? A container — a self-contained package that already includes everything the app needs.

🧳 A container = a suitcase with code, tools, and everything else bundled in.

Docker is the program that runs those suitcases — right on your machine.


Scene 2: “Download and install Docker”#

📝 Do this:

  1. Go to 👉 https://www.docker.com/products/docker-desktop
  2. Choose Docker Desktop for macOS (or your OS).
  3. Download the installer.
  4. Install like any other app: drag the Docker icon into your Applications folder.

📌 Once it’s installed — launch Docker Desktop (via Spotlight or Launchpad).

Quick check: is Docker working?#

🔧 Open Terminal (Cmd + Space, type “Terminal”).

Run this command:

Terminal window
bash docker --version

You should see something like:

Docker version 24.0.2, build abc123

That means Docker is installed!

Next, run:

Terminal window
docker ps

If Docker is running, you’ll see an empty table, like:

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

That’s totally fine — it just means no containers are running yet.

😱 If Docker doesn’t start or docker ps throws an error:

🧨 What’s happening💡 Try this
docker ps doesn’t workMake sure Docker Desktop is running — look for the 🐳 icon in your top menu bar
Command not foundRestart your Terminal or reboot your machine
Docker launched, but nothing’s happeningThe first launch can take a couple of minutes — be patient
It’s asking for permissionsCheck if macOS is waiting for you to approve something — a pop-up might be hiding behind other windows

Why does this matter?#

We’ll be launching our Kubernetes cluster using Minikube, and Minikube runs containers under the hood.

No Docker = no cluster = no “Hello, Pod.” 😬

✅ TL;DR — You’re ready to move on if:

  • You installed Docker Desktop
  • docker --version works
  • docker ps shows an empty table (and no errors)

If all that’s good — let’s install Kubernetes (via Minikube)!


Step 2 — Installing Minikube & kubectl (and launching your first cluster!)#

Scene 1: “What are Minikube and kubectl?”#

🛠 Minikube is like a mini version of Kubernetes you can run right on your laptop.

That means: no server, no cloud, no AWS, no mystical cluster setup — Minikube spins it all up locally.

🎮 kubectl (say “cube control” or “kube cuddle”) is your remote control for that cluster.

You’ll use kubectl to create pods, check logs, update apps — basically, run the show.

Scene 2: Install kubectl and Minikube#

📝 If you’re on a Mac:

Open Terminal and run these one by one:

Terminal window
brew install kubectl

Then:

Terminal window
brew install minikube

🧘‍♀️ Take a moment, let Homebrew do its magic.

Scene 3: Start the cluster#

Once it’s installed, fire up your mini-cluster:

Terminal window
minikube start --driver=docker

💡 What’s happening here:

  • Kubernetes is starting inside Docker (which you set up in Step 1).
  • Minikube creates a “virtual machine” running your cluster.

⏱ This may take 1-2 minutes, so… deep breath.

Check if everything’s working#

Run this command:

Terminal window
kubectl get nodes

📋 You should see something like:

NAME STATUS ROLES AGE VERSION
minikube Ready control-plane 1m v1.29.0

If you see STATUS: Ready - congrats! 🎉

Your first cluster is up. You literally just spun up your own infrastructure.

📌 Quick note:

Minikube runs a single-node cluster - perfect for learning and testing, but not meant for production. And that’s totally fine — we’re here to get hands-on, not deploy Netflix.


If something goes wrong - don’t panic!#

🔥 Problem💡 What to check🛠 Example
kubectl not recognizedDid the install finish cleanly? Try restarting your terminal.
minikube won’t startIs Docker Desktop running? Look for the 🐳 icon.
minikube start just hangsTry restarting Docker, rebooting, and make sure you’ve got at least 4 GB of free RAM
kubectl get nodes shows nothingCheck if the cluster is runningminikube status
Cluster not startedJust run it againminikube start

Why did we do this?#

  • Kubernetes is how you run and manage container-based apps.
  • Minikube lets you explore it without needing cloud servers.
  • kubectl is your command center.

Now you’re ready to create pods, deployments, services - everything a true DevOps witch needs.


Step 3 — My First Pod: Running an App in Kubernetes#

Scene 1: “What even is a Pod?”#

📦 In Kubernetes, everything revolves around Pods.

Think of a Pod as a little room with one (or more) containers inside that:

  • share network and storage
  • start together
  • live and die together

A Pod usually runs just one container (like our nginx example) - but it can have multiple, like sidecars.

Scene 2: Create a YAML file for your Pod#

📁 Open VS Code or your favorite code editor. Create a new file and name it:

Terminal window
pod.yaml

✍️ Paste this inside:

apiVersion: v1
kind: Pod
metadata:
name: my-first-pod
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80

What’s going on here:

  • apiVersion, kind, metadata — just Kubernetes boilerplate: “this is a Pod, name it like this”.
  • Inside containers: you’re saying: “Run a container using nginx and open port 80.”

Scene 3: Apply the file and launch the Pod#

In your terminal, while inside the folder with the file:

Terminal window
kubectl apply -f pod.yaml

👉 This tells Kubernetes: “Here’s the definition — go make it real!”

Then check:

Terminal window
kubectl get pods

You should see something like:

NAME READY STATUS RESTARTS AGE
my-first-pod 1/1 Running 0 10s

STATUS: Running means your Pod is alive and well! 🎉

Scene 4: Open your app in the browser#

Now let’s actually see nginx in action. Time to forward that port:

Terminal window
kubectl port-forward pod/my-first-pod 8080:80

💡 What’s this doing?

  • It tunnels port 80 from inside the container to your localhost:8080.
  • Meaning: whatever nginx serves, you can see in your browser.

Scene 5: Check if it’s working#

Pop open your browser and go to:

http://localhost:8080

If you see the default nginx page — boom, success!

If it didn’t work — deep breath, let’s fix it#

🔥 Problem💡 What to try🛠 Command
Browser says “site can’t be reached”Make sure the terminal with port-forward is still open
kubectl port-forward hangs or failsCancel it (Ctrl + C) and try againkubectl port-forward pod/my-first-pod 8080:80
Port 8080 is already in useTry a different portkubectl port-forward pod/my-first-pod 8081:80 and go to localhost:8081
nginx didn’t start in the PodCheck the logskubectl logs my-first-pod

So far, you’ve:

✅ Started your cluster
✅ Created your very first Pod
✅ Launched nginx
✅ Accessed it through the browser

This was your first real app running in Kubernetes — and that’s a huge milestone 👏👏👏


Step 4 — Deployment: So Your Pods Don’t Break (And If They Do — They Auto-Heal)#

Scene 1: “What is a Deployment, anyway?”#

In the last step, you manually created a Pod. But here’s the problem:

  • If it crashes — nobody restarts it
  • You want two Pods for reliability
  • You want Kubernetes to watch over them automatically

🎯 Enter the Deployment. It:

✅ creates Pods
✅ scales them (1, 2, 10, 100 — whatever)
✅ restarts them if they crash
✅ makes it easy to update images

Basically — a Pod manager that keeps your app alive and thriving.

Scene 2: Create the Deployment YAML#

📁 Create a new file called:

Terminal window
deployment.yaml

✍️ Paste this in:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80

💡 What’s happening here:

  • replicas: 2 — we’re saying “Give me 2 identical Pods”
  • selector.matchLabels + template.metadata.labels — this connects the Deployment to the Pods via app: nginx
  • containers — same as before: launch nginx

Scene 3: Apply the Deployment#

Open your terminal and run this:

Terminal window
kubectl apply -f deployment.yaml

🔍 You’re telling Kubernetes: “Here’s the blueprint — build it.”

Now check that it worked:

Terminal window
kubectl get deployments

You should see something like:

NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 2/2 2 2 10s

✅ Which means: 2 Pods are up and running.

Now check the actual Pods:

Terminal window
kubectl get pods

You should see two Pods with similar names, like:

nginx-deployment-xxx-yyy 1/1 Running
nginx-deployment-aaa-bbb 1/1 Running

Scene 4: Let’s test the auto-recovery#

🧪 Tiny experiment: delete one of the Pods

Terminal window
kubectl delete pod <one-of-the-pod-names>

A few seconds later:

Terminal window
kubectl get pods

You’ll see 2 Pods again.

🤯 Because the Deployment noticed one was gone — and created a new one automatically!

If the Deployment doesn’t launch or Pods don’t appear#

🔥 Problem💡 What to check🛠 Example Command
kubectl apply -f deployment.yaml does nothingMake sure the file is named correctly and you’re in the right folderls
kubectl get deployments shows nothingCould be a YAML error (indentation, missing keys)Run kubectl apply -f deployment.yaml again to see the error
Pods crash (STATUS: CrashLoopBackOff)Something is breaking inside the container — check the logskubectl logs <pod-name>
Don’t know the Pod nameJust list all Podskubectl get pods
error: unable to recognizeYour YAML might be broken — check the formatUse YAML Linter

📌 Pro tip: You can always list Pods with:

Terminal window
kubectl get pods

Why this matters#

Now you’ve got:

  • Two Pods = more reliability
  • Self-healing containers
  • Easy updates in the future

You just leveled up from “one test container” to a real Kubernetes-managed application.


Step 5 — Service: How to Open a Pod in the Browser (Without Magic)#

Scene 1: “What is a Service?”#

You already launched 2 nginx Pods — but right now, they’re hiding behind a wall.

🙅‍♀️ Without a Service, you can’t just open them in the browser. Because:

  • Pods have internal IPs
  • They’re not accessible from “outside”
  • If a Pod restarts, its IP might change

🎯 A Service is like a stable front door to your app.

It knows where your Pods are and routes traffic to them.

Even if a Pod dies, restarts, or moves — the Service still leads to the right place.

Scene 2: Create service.yaml#

📁 Create a new file and name it:

Terminal window
service.yaml

✍️ Paste this in:

apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080

💡 What this does:

  • type: NodePort — tells Kubernetes: “Expose this to the outside world via a port”
  • selector: app: nginx — the Service will forward traffic to Pods with that label
  • port — the port the Service listens on (inside the cluster)
  • targetPort — where to send traffic inside the Pod (nginx listens on port 80)
  • nodePort — the external port you’ll use in your browser

Scene 3: Apply the Service#

In your terminal:

Terminal window
kubectl apply -f service.yaml

🎉 Boom — your Service is live!

Now run this:

Terminal window
minikube service nginx-service

🪄 That command will automatically open your site in the browser — no need to worry about ports, IPs, or voodoo.

Didn’t open? You can do it manually:

Terminal window
minikube ip

👉 You’ll get an IP, like 192.168.49.2

Now go to:

http://192.168.49.2:30080

✅ You should see the nginx welcome page!

What did we just do?#

  • You created a Service to route traffic to your Pods
  • Used NodePort to make it accessible from outside
  • Opened a real website running inside Kubernetes — without port-forward

You’re now officially at the “my app runs in K8s and opens in a browser” level —

aka your very first Kubernetes web app prototype!


Step 6 — ConfigMap: Passing Variables Into a Container (No Rebuilding Needed)#

Scene 1: “Why do we even need ConfigMap?”#

Let’s say you’ve got a website. And now you want to:

  • show a different welcome message
  • tweak the behavior without rebuilding the image
  • keep settings separate from your code

📦 ConfigMap is how you pass variables into your Pods.

Think of it like: “Here’s a YAML with your config — grab it when you start up.”

Scene 2: Create the ConfigMap#

📁 Create a file called:

Terminal window
configmap.yaml

✍️ Paste this:

apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
WELCOME_MSG: "Hello from ConfigMap!"

✨ What’s going on here:

  • data: is just a key-value map
  • WELCOME_MSG is an example string (but it could be a URL, a mode, a path — anything)

Scene 3: Update your deployment.yaml#

Open your deployment.yaml and inside the container block, add this under spec.containers[0]:

env:
- name: WELCOME_MSG
valueFrom:
configMapKeyRef:
name: nginx-config
key: WELCOME_MSG

📌 This tells Kubernetes: “When launching the container, pass it this environment variable from the ConfigMap.”

Scene 4: Apply it all#

In your terminal, run:

Terminal window
kubectl apply -f configmap.yaml
kubectl apply -f deployment.yaml

🔄 This updates both the ConfigMap and the Deployment so everything is hooked up.

Scene 5: Check if the variable is inside the container#

First, get the name of one of the Pods:

Terminal window
kubectl get pods

Copy a name (like nginx-deployment-xxx-yyy) and jump inside:

Terminal window
kubectl exec -it nginx-deployment-xxx-yyy -- /bin/sh

Now run:

Terminal window
echo $WELCOME_MSG

✅ You should see:

Hello from ConfigMap!

🎉 It worked! The variable made it all the way into your container from Kubernetes.

If the variable didn’t show up#

🔥 Problem💡 Check this🛠 Example command
echo $WELCOME_MSG shows nothingMake sure you saved changes and re-applied deployment.yamlkubectl apply -f deployment.yaml
It looks right but still no variableThe Pod may not have restarted — delete it manually and let Deployment recreate itkubectl delete pod <pod_name>
Can’t get into the PodDouble-check the Pod namekubectl get pods
kubectl exec doesn’t workPod may have crashed — check status or logskubectl get pods, kubectl logs <pod_name>

📌 Pro tip: For the new config to appear, the Pod usually has to be recreated.

kubectl apply updates the Deployment, but won’t restart running Pods.

What did you just do?#

  • Created a config variable in Kubernetes
  • Passed it into a Pod via Deployment
  • Saw the variable live inside your container

This is key when your app needs to be flexible — change config without rebuilding the Docker image.


Step 7 — Secret: Safely Passing Passwords and Tokens into a Pod#

Scene 1: “ConfigMap vs Secret — what’s the difference?”#

💡 ConfigMap — for regular settings: modes, messages, URLs.

🔐 Secret — for anything you don’t want exposed to the world:

  • passwords
  • access tokens
  • API keys

❗ Heads up: Secret values are automatically base64-encoded.

That’s not encryption — just a way to hide them from curious eyes.

Scene 2: Create a secret file#

📁 Create a new file:

Terminal window
secret.yaml

✍️ Paste this:

apiVersion: v1
kind: Secret
metadata:
name: nginx-secret
type: Opaque
data:
SECRET_MSG: SGVsbG8sIGZyb20gU2VjcmV0IQ==

✨ What’s going on:

  • type: Opaque — standard type of Secret
  • data: — key-value pairs (in base64)

📌 Example:

Terminal window
echo -n "Hello, from Secret!" | base64

Which gives you: SGVsbG8sIGZyb20gU2VjcmV0IQ==

Open your deployment.yaml.

Inside containers > env, add:

- name: SECRET_MSG
valueFrom:
secretKeyRef:
name: nginx-secret
key: SECRET_MSG

📌 Works exactly like ConfigMap — just a different data source: a Secret.

Scene 4: Apply the changes#

In your terminal:

Terminal window
kubectl apply -f secret.yaml
kubectl apply -f deployment.yaml

📦 Kubernetes will update the Secret and roll out the changes.

Scene 5: Check the container#

First, get your Pod’s name:

Terminal window
kubectl get pods

Then hop inside one:

Terminal window
kubectl exec -it <pod_name> -- /bin/sh

Now check the variable:

Terminal window
echo $SECRET_MSG

✅ You should see:

Hello, from Secret!

🎉 That means your Secret was passed into the container successfully!

If the Secret variable didn’t show up#

🔥 Problem💡 Check this🛠 Example command
echo $SECRET_MSG shows nothingMake sure you saved and re-applied deployment.yamlkubectl apply -f deployment.yaml
Secret wasn’t createdVerify it’s actually therekubectl get secrets
Pod didn’t restartDelete it manually — Deployment will recreate itkubectl delete pod <pod_name>
base64 was wrongMake sure you encoded without newline`echo -n “Hello”
Can’t enter the PodDouble-check the Pod namekubectl get pods

📌 Pro tip: If the variable doesn’t show up after apply, manually deleting the Pod usually helps.

Why does this matter?#

🔐 Secret is the standard way to safely pass sensitive data into your app — no hardcoding, no YAML leaks.

You just:

  • created a Kubernetes Secret
  • passed it into a container
  • verified it from the inside

Magic. Secure magic. 💫

⏸️ Now pause for a second.

Do you realize what you’ve just done?

You installed a cluster. Deployed an app. Passed it configs and secrets — the full DevOps starter pack.

🤯 No clouds. No five tabs of Stack Overflow. No fear of hitting Enter.

Let’s wrap it all up in a beautiful summary:


Final Recap — What You Did and Why It Matters#

StepWhat You DidWhy It Matters
1Installed DockerRuns containers — the foundation for Kubernetes
2Installed Minikube and kubectlLocal cluster and control tool
3Created a PodRan your first app in Kubernetes
4Set up a DeploymentManages and scales Pods automatically
5Added a ServiceMade your app accessible from the browser
6Connected a ConfigMapPassed env vars without rebuilding the image
7Connected a SecretSecurely passed passwords and sensitive data

✨ You just built a mini-infrastructure on your own laptop.

This isn’t just “hello world” — it’s hello Kubernetes.


So, what’s next? Two paths:#

Want to take a break and return later?#

  1. Stop the cluster:
Terminal window
minikube stop
  1. Optionally quit Docker Desktop:

    Click the 🐳 icon in the top bar → Quit Docker Desktop

🛑 That’s like hitting “pause.”

Nothing will be deleted — everything stays just as it is.

👉 When you want to come back:

  • Start Docker Desktop
  • Then run:
Terminal window
minikube start

💡 And boom — your Pods, Services, Configs, Secrets… all back in action.

Not planning to return?#

If you want to fully clean up everything we built:

Terminal window
minikube delete

This removes the cluster, all Pods, configs, and secrets — clean slate.

You can leave Docker installed — you’ll probably use it again (a lot).

Even if you never touch Kubernetes again — know this:

You started it. You understood it. You owned it. That’s already a huge step into the DevOps world.


Tools I Personally Trust#

If you want to make your digital life a little calmer — here are two tools I use every day:

🛸 Proton VPN - A trusted VPN that secures your Wi-Fi, hides your IP, and blocks trackers. Even in that no-password café Wi-Fi, you’re safe.

🔑 Proton Pass - A password manager with on-device encryption. Passwords, logins, 2FA — always with you, and only for you.

These are partner links — you won’t pay a cent more, but you’ll be supporting DevOps.Pink. Thank you — it really means a lot 💖


Social Channels#

🎬 YouTube
🐦 X (Twitter)
🎨 Instagram
🐘 Mastodon
🧵 Threads
🎸 Facebook
🦋 Bluesky
🎥 TikTok
💻 LinkedIn
📣 daily.dev Squad
✈️ Telegram
🐈 GitHub


Community of IT Experts#

👾 Discord


Refill My Coffee Supplies#

💖 PayPal
🏆 Patreon
🥤 BuyMeaCoffee
🍪 Ko-fi
Telegram Boost


Is this content AI-generated?

Absolutely not! Every article is written by me, driven by a genuine passion for Docker and backed by decades of experience in IT. I do use AI tools to polish grammar and enhance clarity, but the ideas, strategies, and technical insights are entirely my own. While this might occasionally trigger AI detection tools, rest assured—the knowledge and experience behind the content are 100% real and personal.

Kubernetes on Your Laptop — No Cloud, No Boring Docs, Just Magic
https://www.devops.pink/kubernetes-on-your-laptop-no-cloud-no-boring-docs-just-magic/
Author
Tatiana Mikhaleva
Published at
2025-05-29
License
CC BY-NC-SA 4.0